bzoj 2716 天使玩偶 CDQ分治
2017-07-01 11:01
197 查看
题意,平面内动态加点,每次查询距离目标点曼哈顿距离最短的点,与之的距离
考虑以查询点为原点,其左下角的点与之曼哈顿距离为dis=(x-x')+(y-y')=(x+y)-(x'+y')
因此,我们考虑求(x'+y')最大值
CDQ分治来解决此题
首先考虑将所有点,无论是目标点还是插入的点,按X坐标排序
再对于时间进行分治
对于分治后得到的两段,分别在内部再次按X坐标排序,
之后创建两个指针,分别在,左半块和右半块滑动,并且始终使,右半块中指针所指的查询的点的时间,晚于左半块中插入点的时间
然后动态在树状数组中加入右半块中要插入的点
最后查询X+Y最大值
最后计算一下,直接更改点坐标,是右上等情况也满足左下的情况
共调用cdq 3次
代码如下
考虑以查询点为原点,其左下角的点与之曼哈顿距离为dis=(x-x')+(y-y')=(x+y)-(x'+y')
因此,我们考虑求(x'+y')最大值
CDQ分治来解决此题
首先考虑将所有点,无论是目标点还是插入的点,按X坐标排序
再对于时间进行分治
对于分治后得到的两段,分别在内部再次按X坐标排序,
之后创建两个指针,分别在,左半块和右半块滑动,并且始终使,右半块中指针所指的查询的点的时间,晚于左半块中插入点的时间
然后动态在树状数组中加入右半块中要插入的点
最后查询X+Y最大值
最后计算一下,直接更改点坐标,是右上等情况也满足左下的情况
共调用cdq 3次
代码如下
#include<bits/stdc++.h> using namespace std; const int N=1001000; struct node{ bool is_ques; int x,y,id; }P ,sort_by_time ; int e ,ans ,vis ; int n,m,cnt=0; inline void R(int &x) { x=0; char c=getchar(); int p=1; while(c<'0'||c>'9') { if(c=='-') p=-1; c=getchar(); } while(c>='0'&&c<='9') { x=(x<<1)+(x<<3)+(c^'0'); c=getchar(); } x*=p; } bool comp(node a,node b){return a.x<b.x;} int lowbit(int x) {return x&(-x);} void add(int pos,int val) { if(!pos)return; while(pos<N) { e[pos]=max(e[pos],val); pos+=lowbit(pos); } } int query(int pos) { int res=-1; while(pos>0) { res=max(res,e[pos]); pos-=lowbit(pos); } return res; } void release(int pos) { if(!pos)return; while(pos<N)e[pos]=-1,pos+=lowbit(pos); } void cdq(int l,int r) { if(l==r)return; int mid=l+r>>1; int c1=l,c2=mid+1; for(int i=l;i<=r;i++) { if(P[i].id<=mid) sort_by_time[c1++]=P[i]; else sort_by_time[c2++]=P[i]; } for(int i=l;i<=r;i++)P[i]=sort_by_time[i]; int j=l,temp=0; for(int i=mid+1;i<=r;i++) { if(P[i].is_ques) { while(P[j].x<=P[i].x&&j<=mid) { if(!P[j].is_ques)add(P[j].y,P[j].x+P[j].y); vis[++temp]=P[j].y; j++; } int maxx=query(P[i].y); if(maxx!=-1) ans[P[i].id]=min(ans[P[i].id],P[i].x+P[i].y-maxx); } } for(int i=1;i<=temp;i++)release(vis[i]); cdq(l,mid); cdq(mid+1,r); } int main() { // freopen("in.in","r",stdin); R(n);R(m); int t,x,y,Max=-1; for(int i=1;i<=n;i++) { R(x);R(y); cnt++; P[cnt].id=cnt; P[cnt].x=x; P[cnt].y=y; Max=max(Max,x); Max=max(Max,y); P[cnt].is_ques=0; } for(int i=1;i<=m;i++) { R(t);R(x);R(y); Max=max(Max,x); Max=max(Max,y); cnt++; P[cnt].id=cnt; P[cnt].x=x; P[cnt].y=y; if(t==1)P[cnt].is_ques=0; else P[cnt].is_ques=1; } // cout<<Max<<endl; sort(P+1,P+cnt+1,comp); memset(e,-1,sizeof(e)); memset(ans,127,sizeof(ans)); cdq(1,cnt); for(int i=1;i<=cnt;i++)P[i].y=Max-P[i].y+1; sort(P+1,P+cnt+1,comp);cdq(1,cnt); for(int i=1;i<=cnt;i++)P[i].x=Max-P[i].x+1; sort(P+1,P+cnt+1,comp);cdq(1,cnt); for(int i=1;i<=cnt;i++)P[i].y=Max-P[i].y+1; sort(P+1,P+cnt+1,comp);cdq(1,cnt); for(int i=n+1;i<=cnt;i++) if(ans[i]<1e9)printf("%d\n",ans[i]); }
相关文章推荐
- BZOJ-2716-天使玩偶angel-CDQ分治
- BZOJ 2716: [Violet 3]天使玩偶 [CDQ分治]
- 【BZOJ 2716/2648】 [Violet 3]天使玩偶 SJY摆棋子
- BZOJ 2716: [Violet 3]天使玩偶 | CDQ分治
- BZOJ 2648 SJY摆棋子 / 2716 Violet 3 天使玩偶 K-D树
- bzoj 2716 [Violet 3]天使玩偶 【CDQ分治】
- BZOJ 2716 [Violet 3]天使玩偶
- bzoj 2648: SJY摆棋子&&2716: [Violet 3]天使玩偶 --kdtree
- bzoj2716 [Violet 3]天使玩偶(CDQ分治)
- [BZOJ2716][Violet 3]天使玩偶(cdq分治||KD-tree)
- bzoj2716: [Violet 3]天使玩偶
- [BZOJ]2716: [Violet 3]天使玩偶 CDQ分治+树状数组
- BZOJ 2716 Violet 3 天使玩偶 CDQ分治
- [BZOJ2716][Violet 3]天使玩偶(cdq分治+bit)
- bzoj2716 [Violet 3]天使玩偶(KDtree)
- 【Violet3】【BZOJ2716】天使玩偶
- bzoj2716 [Violet 3]天使玩偶
- 【BZOJ】2648: SJY摆棋子 & 2716: [Violet 3]天使玩偶(kdtree)
- 【bzoj 2716】[Violet 3]天使玩偶 (cdq分治+树状数组)
- BZOJ.2716.[Violet3]天使玩偶(CDQ分治 坐标变换)