离线, 然后按时间分治, 每个向量都有出现时间[l, r], 直接插入时间线段树(一个向量只会影响O(logN)数量级的线段树节点). 在线段树每个节点弄出凸壳然后二分. 时间复杂度O(Nlog^2N)

---------------------------------------------------------------------------

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
typedef long long ll;
#define V(x) v[p[x]]
#define C(x) v[c[x]]
#define Q(x) q[_q[x]]
#define K(a, b) ((double) (a.y - b.y) / (a.x - b.x))
 
const int maxn = 200009;
 
int N, T, qn, vn, pn, cn;
int p[maxn], _q[maxn], c[maxn];
double lk[maxn], rk[maxn];
ll ans[maxn];
int buf[20];
 
inline int getint() {
char c = getchar();
for(; !isdigit(c); c = getchar());
int ret = 0;
for(; isdigit(c); c = getchar())
ret = ret * 10 + c - '0';
return ret;
}
 
inline void putint(ll x) {
if(!x) {
puts("0");
} else {
int n = 0;
for(; x; x /= 10) buf[n++] = x % 10;
while(n--) putchar(buf[n] + '0');
puts("");
}
}
 
struct Q {
int p, x, y;
} q[maxn];
 
struct V {
int x, y, l, r;
} v[maxn];
 
struct L {
int p;
L* nxt;
} Lpool[maxn * 50], *Lpt = Lpool;
 
inline void AddL(L*&t) {
Lpt->p = T;
Lpt->nxt = t;
t = Lpt++;
}
 
struct Node {
Node *lc, *rc;
L* v;
} pool[maxn << 1], *pt = pool, *Root;
 
void Modify(Node* t, int l, int r) {
if(v[T].l <= l && r <= v[T].r) {
AddL(t->v);
} else {
int m = (l + r) >> 1;
if(v[T].l <= m) Modify(t->lc, l, m);
if(m < v[T].r) Modify(t->rc, m + 1, r);
}
}
 
void Build(Node* t, int l, int r) {
if(l != r) {
int m = (l + r) >> 1;
Build(t->lc = pt++, l, m);
Build(t->rc = pt++, m + 1, r);
}
}
 
bool Cmp(const int &l, const int &r) {
return v[l].x < v[r].x || (v[l].x == v[r].x && v[l].y < v[r].y);
}
 
void Solve(Node* t, int l, int r) {
if(l != r) {
int m = (l + r) >> 1;
Solve(t->lc, l, m);
Solve(t->rc, m + 1, r);
}
pn = cn = 0;
for(L* o = t->v; o; o = o->nxt) p[pn++] = o->p;
if(!pn) return;
sort(p, p + pn, Cmp);
c[cn++] = p[0];
for(int i = 1; i < pn; i++) {
while(cn && V(i).x == C(cn - 1).x) cn--;
while(cn > 1 && K(V(i), C(cn - 1)) > K(C(cn - 1), C(cn - 2))) cn--;
c[cn++] = p[i];
}
lk[0] = 1e30, rk[cn - 1] = -1e30;
for(int i = 1; i < cn; i++)
lk[i] = rk[i - 1] = K(C(i), C(i - 1));
for(int i = l; i <= r; i++) if(~_q[i]) {
int _l = 0, _r = cn - 1;
double k = -1.0 * Q(i).x / Q(i).y;
while(_l <= _r) {
int m = (_l + _r) >> 1;
ans[_q[i]] = max(ans[_q[i]], ll(C(m).x) * Q(i).x + ll(C(m).y) * Q(i).y);
(k < lk[m] && k < rk[m]) ? _l = m + 1 : _r = m - 1;
}
}
}
 
void Work() {
Build(Root = pt++, 1, N);
for(T = 0; T < vn; T++) Modify(Root, 1, N);
pn = 0;
Solve(Root, 1, N);
for(int i = 0; i < qn; i++) putint(ans[i]);
}
 
void Init() {
N = getint();
qn = vn = 0;
memset(_q, -1, sizeof _q);
for(int i = 1; i <= N; i++) {
int t = getint();
if(t == 3) {
_q[i] = qn;
q[qn].x = getint(), q[qn].y = getint();
q[qn++].p = i;
} else if(t == 1) {
v[vn].x = getint(), v[vn].y = getint();
v[vn].l = i, v[vn++].r = N;
} else
v[getint() - 1].r = i;
}
memset(ans, 0, sizeof ans);
}
 
int main() {
Init();
Work();
return 0;
}

---------------------------------------------------------------------------

4311: 向量

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 58  Solved: 26
[Submit][Status][Discuss]

Description

你要维护一个向量集合,支持以下操作:
1.插入一个向量(x,y)
2.删除插入的第i个向量
3.查询当前集合与(x,y)点积的最大值是多少。如果当前是空集输出0

Input

第一行输入一个整数n,表示操作个数
接下来n行,每行先是一个整数t表示类型,如果t=1,输入向量
(x,y);如果t=2,输入id表示删除第id个向量;否则输入(x,y),查询
与向量(x,y)点积最大值是多少。
保证一个向量只会被删除一次,不会删没有插入过的向量

Output

对于每条t=3的询问,输出一个答案

Sample Input

5
1 3 3
1 1 4
3 3 3
2 1
3 3 3

Sample Output

18
15

HINT

n<=200000 1<=x,y<=10^6

Source

BZOJ 4311: 向量( 按时间分治 + 线段树 )的更多相关文章

  1. bzoj 4311 向量 时间线建线段树+凸包+三分

    题目大意 你要维护一个向量集合,支持以下操作: 1.插入一个向量(x,y) 2.删除插入的第i个向量 3.查询当前集合与(x,y)点积的最大值是多少.如果当前是空集输出0 分析 按时间线建线段树 大致 ...

  2. [BZOJ1018][SHOI2008]堵塞的交通traffic 时间分治线段树

    题面 介绍一种比较慢的但是好想的做法. 网上漫天的线段树维护联通性,然后想起来费很大周折也很麻烦.我的做法也是要用线段树的,不过用法完全不同. 这个东西叫做时间分治线段树. 首先我们建一个\(1..m ...

  3. 2019ICPC上海网络赛A 边分治+线段树

    题目: 给定一棵树, 带边权. 现在有2种操作: 1.修改第i条边的权值. 2.询问u到其他一个任意点的最大距离是多少. 解法:边分治+线段树 首先我们将所有的点修改和边修改都存在对应的边里面. 然后 ...

  4. UVALive 7148 LRIP【树分治+线段树】

    题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...

  5. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  6. 【BZOJ4372】烁烁的游戏 动态树分治+线段树

    [BZOJ4372]烁烁的游戏 Description 背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠.题意:给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠.烁烁他每次会跳到一个节点u,把周围与他距 ...

  7. 【bzoj4372】烁烁的游戏 动态点分治+线段树

    题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:Q x:询问x的点权.M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m接下来的n-1 ...

  8. 【bzoj3730】震波 动态点分治+线段树

    题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...

  9. 洛谷T44252 线索_分治线段树_思维题

    分治线段树,其实就是将标记永久化,到最后再统一下传所有标记. 至于先后顺序,可以给每个节点开一个时间戳. 一般地,分治线段树用于离线,只查询一次答案的题目. 本题中,标记要被下传 222 次. Cod ...

随机推荐

  1. Linux 下编译Android-VLC开源播放器详解(附源码下载)

    这两天需要做音视频播放相关的东西,所以重新找了目前android下的解码库.Android自带的解码库支持不全,因此很多第三方播放器都是自带解码器,绝大部分都是使用FFMpeg作为解码库.我11年的时 ...

  2. .net通用权限框架B/S (三)--MODEL层(2)

    接上篇 实体数据模型保存后生成上下文和实体 上下文和实体实际是由根据.tt模版生成的 当实体数据模型.edmx更新保存后,上下文和实体就会根据.tt模版自动更新 生成的上下文继承 DbContext ...

  3. Nodejs随笔(一):Hello World!

    声明:本人用的是Ubuntu 14.04 LTS 系统. 一.Nodejs安装: <1>直接apt-get安装,最简单:sudo apt-get install nodejs <2& ...

  4. Schema-based AOP support

    本文参考至:spring-framework-reference.pdf的7.3 章节 [Schema-based AOP support] If you are unable to use Java ...

  5. js——DOM操作(二)

    表格属性: tHead:表格头 tBodies:表格正文 tFoot:表格尾 rows:行 cells:列 表单操作: <form id="form1"> <in ...

  6. CDH(cdh5.7) 上集成 kafka

    CDH 可以在线下载: 离线安装

  7. emoji表情字符串 mysql 普通 utf8 格式无法存入

    处理方法: 1.在可以忽略emoji表情的情况下,可以选择将emoji表情字符过滤掉,这样不用动mysql 表结构    过滤Java代码参考如下: public static String filt ...

  8. Windows Server 2008防火墙问题及Sql Server2005用户登录问题

    一.Windows Server 2008防火墙问题 1.  问题: 1.在 Windows 安全中心中单击“立即打开”以打开 Windows 防火墙时,会收到以下错误消息:安全中心无法打开 Wind ...

  9. java中JSON串转换并获取数据

    String strAllImp= " [{"id":2,"name":"还不错","count":3}]&q ...

  10. CSS3 Test

    CSS3Test 如何判定一个浏览器对css3的支持情况呢 有这么一个站点http://css3test.com 可以测试浏览器对CSS3的支持情况 对应的Github在这里 原理 实际上浏览器对CS ...