bzoj 2716 [Violet 3]天使玩偶 【CDQ分治】
KD-tree可做,但是我不会暂时不考虑
大意:在二维平面内,给定n个点,m个操作。操作A:加入一个点;操作B:询问一个点与平面上加入的点的最近距离
不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T不封装会T
把初始存在的点也看成加点操作
首先,曼哈顿距离取绝对值很烦,所以我们可以通过转坐标,把左上 右上 左下 右下通过转坐标都变成左下,最后取个min即可。于是对于(x,y)左下的点(x1,y1),dis=x-x1+y-y1=(x+y)-(x1+y1),用树状数组维护前缀最小值x1+y1。
按时间序排列,时间序 x y 三维偏序做CDQ分治即可
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int N=1000005,inf=1e9; 6 int n,m,maxx,ans[N]; 7 struct BIT 8 { 9 int c[N]; 10 int lb(int x) 11 { 12 return x&(-x); 13 } 14 void update(int x,int d) 15 { 16 for(int i=x;i<=maxx;i+=lb(i)) 17 c[i]=max(c[i],d); 18 } 19 int ques(int x) 20 { 21 int ret=0; 22 for(int i=x;i>=1;i-=lb(i)) 23 ret=max(ret,c[i]); 24 return ret; 25 } 26 void clear(int x) 27 { 28 for(int i=x;i<=maxx;i+=lb(i)) 29 c[i] = 0; 30 } 31 }bit; 32 struct qwe 33 { 34 int x,y,k,id; 35 bool operator < (const qwe& rhs) const 36 { 37 if(x != rhs.x) 38 return x < rhs.x; 39 return id < rhs.id; 40 } 41 }a[N]; 42 struct CDQ 43 { 44 int n; 45 qwe T[N]; 46 void init(int n) 47 { 48 this->n=n; 49 sort(a+1,a+n+1); 50 } 51 void solve(int L, int R) 52 { 53 if(L>=R) 54 return; 55 int M=(L+R)>>1; 56 int p=L,q=M+1; 57 for(int i=L;i<=R;i++) 58 if(a[i].id<=M) 59 T[p++]=a[i]; 60 else 61 T[q++]=a[i]; 62 for(int i=L;i<=R;i++) 63 a[i]=T[i]; 64 solve(L,M); 65 solve(M+1,R); 66 int i=M+1,j=L; 67 for(;i<=R;i++) 68 if(a[i].k==2) 69 { 70 for(;j<=M&&a[j].x<=a[i].x;j++) 71 if(a[j].k==1) 72 bit.update(a[j].y,a[j].x+a[j].y); 73 int t=bit.ques(a[i].y); 74 if(t) 75 ans[a[i].id]=min(ans[a[i].id],a[i].x+a[i].y-t); 76 } 77 for(int i=L;i<j;i++) 78 if(a[i].k==1) 79 bit.clear(a[i].y); 80 merge(a+L,a+M+1,a+M+1,a+R+1,T+L); 81 for(int i=L;i<=R;i++) 82 a[i]=T[i]; 83 } 84 }cdq; 85 int read() 86 { 87 int r=0; 88 char p=getchar(); 89 while(p>'9'||p<'0') 90 p=getchar(); 91 while(p>='0'&&p<='9') 92 { 93 r=r*10+p-48; 94 p=getchar(); 95 } 96 return r; 97 } 98 int main() 99 { 100 n=read(),m=read(); 101 for(int i=1;i<=n;i++) 102 { 103 a[i].x=read()+1; 104 a[i].y=read()+1; 105 a[i].id=i; 106 a[i].k=1; 107 maxx=max(maxx,max(a[i].x,a[i].y)); 108 } 109 for(int i=n+1;i<=n+m;i++) 110 { 111 a[i].k=read(); 112 a[i].x=read()+1; 113 a[i].y=read()+1; 114 a[i].id=i; 115 maxx=max(maxx,max(a[i].x,a[i].y)); 116 } 117 maxx++; 118 n+=m; 119 for(int i=1;i<=n;i++) 120 ans[i]=inf; 121 cdq.init(n); 122 cdq.solve(1,n); 123 for(int i=1;i<=n;i++) 124 a[i].x=maxx-a[i].x; 125 cdq.init(n); 126 cdq.solve(1,n); 127 for(int i=1;i<=n;i++) 128 a[i].y=maxx-a[i].y; 129 cdq.init(n); 130 cdq.solve(1,n); 131 for(int i=1;i<=n;i++) 132 a[i].x=maxx-a[i].x; 133 cdq.init(n); 134 cdq.solve(1,n); 135 for(int i=1;i<=n;i++) 136 if(ans[i]!=inf) 137 printf("%d\n",ans[i]); 138 return 0; 139 }