1941: [Sdoi2010]Hide and Seek|动态加点线段树
2016-03-11 15:42
435 查看
传统的K-Dtree姿势http://blog.csdn.net/ws_yzy/article/details/50855522
对计算曼哈顿距离分四种情况讨论,枚举每一个点,维护它的左下,左上,右下,右上的点,在相同区域的点的计算曼哈顿距离的符号是相同的
先用左下方的点更新每一个点,对于点(x,y),此时线段树中存的是−x−y,维护最大值和最小值
从左到右枚举每一个点(x,y),询问线段树中区间[0,y]中的最大值和最小值来更新到这个点的距离的最值,然后在将该点插入到线段树中
其他区域也同理
对计算曼哈顿距离分四种情况讨论,枚举每一个点,维护它的左下,左上,右下,右上的点,在相同区域的点的计算曼哈顿距离的符号是相同的
先用左下方的点更新每一个点,对于点(x,y),此时线段树中存的是−x−y,维护最大值和最小值
从左到右枚举每一个点(x,y),询问线段树中区间[0,y]中的最大值和最小值来更新到这个点的距离的最值,然后在将该点插入到线段树中
其他区域也同理
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<set> #include<map> #include<iostream> #include<algorithm> #define N 4000022 #define M 500050 using namespace std; int sc() { int i=0,f=1; char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar(); return i*f; } struct W{int x,y;}a[M]; int mn ,mx ,ll ,lr ,cnt; int ans1[M],ans2[M]; int n,MX,root,ans=1e9; bool cmp(W a,W b) { return a.x<b.x; } void push_up(int x) { mn[x]=min(mn[ll[x]],mn[lr[x]]); mx[x]=max(mx[ll[x]],mx[lr[x]]); } void insert(int &x,int l,int r,int p,int v) { if(l==r) { if(x) mn[x]=min(mn[x],v), mx[x]=max(mx[x],v); else x=++cnt,mn[x]=mx[x]=v; return; } if(!x)x=++cnt; int mid=l+r>>1; if(p<=mid)insert(ll[x],l,mid,p,v); else insert(lr[x],mid+1,r,p,v); push_up(x); } int query_mx(int x,int L,int R,int l,int r) { if(!x)return -1e9; if(L==l&&R==r)return mx[x]; int mid=L+R>>1; if(r<=mid)return query_mx(ll[x],L,mid,l,r); else if(l>mid)return query_mx(lr[x],mid+1,R,l,r); else return max(query_mx(ll[x],L,mid,l,mid),query_mx(lr[x],mid+1,R,mid+1,r)); } int query_mn(int x,int L,int R,int l,int r) { if(!x)return 1e9; if(L==l&&R==r)return mn[x]; int mid=L+R>>1; if(r<=mid)return query_mn(ll[x],L,mid,l,r); else if(l>mid)return query_mn(lr[x],mid+1,R,l,r); else return min(query_mn(ll[x],L,mid,l,mid),query_mn(lr[x],mid+1,R,mid+1,r)); } int main() { mn[0]=1e9,mx[0]=-1e9; n=sc(); for(int i=1;i<=n;i++) ans1[i]=-1e9,ans2[i]=1e9, a[i].x=sc(),a[i].y=sc(), MX=max(MX,max(a[i].x,a[i].y)); sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) { ans1[i]=max(ans1[i],a[i].x+a[i].y+query_mx(root,0,MX,0,a[i].y)); ans2[i]=min(ans2[i],a[i].x+a[i].y+query_mn(root,0,MX,0,a[i].y)); insert(root,0,MX,a[i].y,-a[i].x-a[i].y); } for(int i=1;i<=cnt;i++) ll[i]=lr[i]=0; root=cnt=0; for(int i=1;i<=n;i++) { ans1[i]=max(ans1[i],a[i].x-a[i].y+query_mx(root,0,MX,a[i].y,MX)); ans2[i]=min(ans2[i],a[i].x-a[i].y+query_mn(root,0,MX,a[i].y,MX)); insert(root,0,MX,a[i].y,-a[i].x+a[i].y); } for(int i=1;i<=cnt;i++) ll[i]=lr[i]=0; root=cnt=0; for(int i=n;i>=1;i--) { ans1[i]=max(ans1[i],-a[i].x+a[i].y+query_mx(root,0,MX,0,a[i].y)); ans2[i]=min(ans2[i],-a[i].x+a[i].y+query_mn(root,0,MX,0,a[i].y)); insert(root,0,MX,a[i].y,a[i].x-a[i].y); } for(int i=1;i<=cnt;i++) ll[i]=lr[i]=0; root=cnt=0; for(int i=n;i>=1;i--) { ans1[i]=max(ans1[i],-a[i].x-a[i].y+query_mx(root,0,MX,a[i].y,MX)); ans2[i]=min(ans2[i],-a[i].x-a[i].y+query_mn(root,0,MX,a[i].y,MX)); insert(root,0,MX,a[i].y,a[i].x+a[i].y); } for(int i=1;i<=n;i++) ans=min(ans,ans1[i]-ans2[i]); cout<<ans; return 0; }
相关文章推荐
- 线段树题集
- 线段树
- hdu1754
- HDU1394
- 敌兵布阵 (1)
- I Hate It (1)
- LCIS (2)
- A Simple Problem with Integers (2)
- Mayor's posters (3)
- Buy Tickets (3)
- 线段树
- UVA - 12532 Interval Product
- POJ 3264 Balanced Lineup
- hdu 1542 求矩形并的面积
- 关于数据结构之线段树
- poj 3225 关于集合运算
- poj 2352
- hihocoder #1069 线段树
- hdu1166敌兵布阵(线段树点修改)
- 【51nod 6级题目】XOR key 问题