BZOJ_4311_向量_CDQ分治+线段树按时间分治

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

Ans=x1*x+y1*y。
y1=-x/y *x1+Ans/y。
因为y是正数,也就是说我们只需要y轴正无穷的地方能看到的点。
于是维护上凸壳即可。
但是不会删除,考虑线段树按时间分治,对log个节点上用vector插入这个点。
然后[l,r]这段的询问向上找,在线段树的结点上用vector里的点更新答案。
可以预先把插入的点按横坐标排序,这样求凸壳就是O(n)的了。
并且询问也可以向上归并,时间复杂度O(nlogn)。
 
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
inline char nc() {
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
int rd() {
int x=0; char s=nc();
while(s<'0'||s>'9') s=nc();
while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
return x;
}
typedef long long ll;
typedef double f2;
#define ls p<<1
#define rs p<<1|1
#define N 200050
struct Point {
ll x,y;
Point() {}
Point(ll x_,ll y_) :
x(x_),y(y_) {}
};
struct A {
Point p;
int bg,ed;
bool operator < (const A &u) const {
return p.x<u.p.x;
}
}P[N];
f2 Slp(const Point &p1,const Point &p2) {
if(p1.x==p2.x) return p2.y>p1.y?1e18:-1e18;
return 1.0*(p2.y-p1.y)/(p2.x-p1.x);
}
ll f[N];
f2 qk[N];
ll qx[N],qy[N];
vector<Point>V[N<<2];
int n,m,id,t[N],tmp[N];
Point S[N];
void update(int l,int r,int x,int y,int p,Point pp) {
if(x<=l&&y>=r) {
V[p].push_back(pp); return ;
}
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,y,ls,pp);
if(y>mid) update(mid+1,r,x,y,rs,pp);
}
Point pp;
void solve(int l,int r,int p) {
int i,lim;
if(l==r) {
lim=V[p].size();
for(i=0;i<lim;i++) {
pp=V[p][i];
f[l]=max(f[l],pp.x*qx[l]+pp.y*qy[l]);
}
return ;
}
int mid=(l+r)>>1;
solve(l,mid,ls); solve(mid+1,r,rs);
int j=l,k=mid+1; i=l;
while(j<=mid&&k<=r) {
if(qk[t[j]]>=qk[t[k]]) tmp[i++]=t[j++];
else tmp[i++]=t[k++];
}
while(j<=mid) tmp[i++]=t[j++];
while(k<=r) tmp[i++]=t[k++];
for(i=l;i<=r;i++) t[i]=tmp[i];
lim=V[p].size();
if(lim==0) return ;
int top=0;
for(i=0;i<lim;i++) {
pp=V[p][i];
while(top>1&&Slp(S[top-1],S[top])<=Slp(S[top-1],pp)) top--;
S[++top]=pp;
}
j=1;
for(i=l;i<=r;i++) {
while(j<top&&Slp(S[j],S[j+1])>=qk[t[i]]) j++;
f[t[i]]=max(f[t[i]],qx[t[i]]*S[j].x+qy[t[i]]*S[j].y);
}
}
int main() {
// freopen("tt.in","r",stdin);
// freopen("tt.out","w",stdout);
n=rd();
int opt,i,x,y;
for(i=1;i<=n;i++) {
opt=rd();
if(opt==1) {
x=rd(); y=rd();
P[++id].p=Point(x,y);
P[id].bg=m+1;
}else if(opt==2) {
x=rd();
P[x].ed=m;
if(!m) P[x].ed=-1;
}else {
m++; x=rd(); y=rd();
qk[m]=(-1.0*x/y);
qx[m]=x; qy[m]=y;
}
}
sort(P+1,P+id+1);
for(i=1;i<=id;i++) {
if(P[i].bg<=m&&P[i].ed!=-1) {
P[i].ed=P[i].ed?P[i].ed:m;
update(1,m,P[i].bg,P[i].ed,1,P[i].p);
}
// printf("%d %d\n",P[i].bg,P[i].ed);
}
for(i=1;i<=m;i++) t[i]=i;
solve(1,m,1);
for(i=1;i<=m;i++) printf("%lld\n",f[i]);
}

BZOJ_4311_向量_线段树按时间分治的更多相关文章

  1. BZOJ_4025_二分图_线段树按时间分治+并查集

    BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...

  2. 【bzoj4311】向量 线段树对时间分治+STL-vector维护凸包

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

  3. 【CF576E】Painting Edges 线段树按时间分治+并查集

    [CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...

  4. 【BZOJ-4184 】 Shallot 线段树按时间分治 + 线性基

    4184: shallot Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 356  Solved: 180[Submit][Status][Discu ...

  5. BZOJ_4184_shallot_线段树按时间分治维护线性基

    BZOJ_4184_shallot_线段树按时间分治维护线性基 Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻 ...

  6. Bipartite Checking CodeForces - 813F (线段树按时间分治)

    大意: 动态添边, 询问是否是二分图. 算是个线段树按时间分治入门题, 并查集维护每个点到根的奇偶性即可. #include <iostream> #include <sstream ...

  7. 【BZOJ4311】向量(线段树分治,斜率优化)

    [BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...

  8. BZOJ_4636_蒟蒻的数列_线段树+动态开点

    BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...

  9. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

随机推荐

  1. JFinal2.0极速开发视频教程发布【转】

    原文:http://blog.dreamlu.net/blog/79 目前JFinal越来越火爆,而且使用的公司越来越多.鉴于市面上JFinal的学习资源不多,我们开始基于JFinal2.0录制学习视 ...

  2. jquery.fullPage.js全屏滚动插件

    注:本文内容复制于http://www.51xuediannao.com/js/jquery/jquery.fullPage.html 和 http://www.360doc.com/content/ ...

  3. HDU 5676 ztr loves lucky numbers【DFS】

    题目链接; http://acm.hdu.edu.cn/showproblem.php?pid=5676 题意: 由4和7组成的且4和7出现次数相同的数称为幸运数字,给定n,求不大于n的最大幸运数字. ...

  4. BZOJ——1614: [Usaco2007 Jan]Telephone Lines架设电话线

    Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1930  Solved: 823[Submit][Status][Discuss] Description ...

  5. Spring实战Day6

    3.4 bean的作用域 Spring中bean的作用域 单例(Singleton):在整个应用中,只创建bean的一个实例. 原型(Prototype):每次注入或者通过Spring应用上下文获取的 ...

  6. Java服务器获取客户端的ip

    原文:http://www.open-open.com/code/view/1454133120089 /** * 获取登录用户IP地址 * * @param request * @return */ ...

  7. iinflux数据库使用

    特殊用法: http://blog.fatedier.com/2016/07/05/research-of-time-series-database-influxdb/ 创建表及表中的key和valu ...

  8. [Node.js] Trigger a File Download in Express

    Downloading and saving a file is a common scenario when building out your web application. Using Exp ...

  9. weex stream 方法封装

    1.封装 api.js // 配置API接口地址 const baseUrl = 'http://www.kuitao8.com/'; // 引入 弹窗组件 var modal = weex.requ ...

  10. c程序设计语言第一章5

    练习1.20请编写程序d e t a b