感人肺腑pascal过不去系列(可能是自己弱,因为有pascal过去了毕竟)
那个这种平面点还有一种处理方法是kd tree,太弱了不会有时间学一下
我还是用了cdq分治,首先肯定要把绝对值这个不和谐的东西去掉
然后就变成了4个部分,这样就非常好维护了,然后还是cdq分治的一般步骤
有优化建议的欢迎指教……
1 const inf=1000000007; 2 type node=record 3 x,y,p,z:longint; 4 end; 5 6 var b,a:array[0..1000010] of node; 7 g,q,c,next,last:array[0..1000010] of longint; 8 v:array[0..1000010] of boolean; 9 ans:array[0..500010] of longint; 10 mx,t,i,j,my,n,m,tot,p:longint; 11 12 function max(a,b:longint):longint; 13 begin 14 if a>b then exit(a) else exit(b); 15 end; 16 17 function min(a,b:longint):longint; 18 begin 19 if a>b then exit(b) else exit(a); 20 end; 21 22 function lowbit(x:longint):longint; 23 begin 24 exit(x and (-x)); 25 end; 26 27 procedure add(x,w:longint); 28 begin 29 while x<=p do 30 begin 31 if not v[x] then 32 begin 33 inc(tot); 34 q[tot]:=x; 35 v[x]:=true; 36 end; 37 c[x]:=max(c[x],w); 38 x:=x+lowbit(x); 39 end; 40 end; 41 42 function ask(x:longint):longint; 43 begin 44 ask:=-inf; 45 while x>0 do 46 begin 47 ask:=max(ask,c[x]); 48 x:=x-lowbit(x); 49 end; 50 end; 51 52 procedure work(s,t,dx,dy:longint); 53 var i,k,y:longint; 54 begin 55 tot:=0; 56 i:=s; 57 while i<>t do 58 begin 59 k:=dx*b[i].x+dy*b[i].y; 60 if dy=-1 then y:=g[my-b[i].y+1] else y:=g[b[i].y]; 61 if b[i].z=1 then 62 add(y,k) 63 else ans[b[i].p-n]:=min(ans[b[i].p-n],abs(k-ask(y))); 64 i:=i+dx; 65 end; 66 for i:=1 to tot do 67 begin 68 c[q[i]]:=-inf; 69 v[q[i]]:=false; 70 end; 71 end; 72 73 procedure cdq(l,r:longint); 74 var m,l1,l2,t,i,tt:longint; 75 begin 76 if l=r then exit; 77 m:=(l+r) shr 1; 78 l2:=0; t:=0; 79 for i:=l to r do 80 if (a[i].z=1) and (a[i].p<=m) then 81 begin 82 inc(t); 83 b[t]:=a[i]; 84 end 85 else if (a[i].z=2) and (a[i].p>m) then 86 begin 87 inc(t); 88 b[t]:=a[i]; 89 inc(l2); 90 end; 91 92 if l2>0 then 93 begin 94 work(1,t+1,1,1); 95 work(t,0,-1,1); 96 work(1,t+1,1,-1); 97 work(t,0,-1,-1); 98 end; 99 t:=l2; tt:=0; 100 l1:=l; l2:=m+1; 101 for i:=l to r do 102 if a[i].p<=m then 103 begin 104 b[l1]:=a[i]; 105 inc(l1); 106 if a[i].z=2 then inc(tt); 107 end 108 else begin 109 b[l2]:=a[i]; 110 inc(l2); 111 end; 112 113 for i:=l to r do 114 a[i]:=b[i]; 115 if tt>0 then cdq(l,m); 116 if t>0 then cdq(m+1,r); 117 end; 118 119 begin 120 readln(n,m); 121 for i:=1 to n do 122 begin 123 readln(b[i].x,b[i].y); 124 inc(b[i].x); 125 inc(b[i].y); 126 b[i].p:=i; 127 b[i].z:=1; 128 my:=max(my,b[i].y); 129 end; 130 for i:=n+1 to n+m do 131 begin 132 readln(b[i].z,b[i].x,b[i].y); 133 inc(b[i].x); 134 inc(b[i].y); 135 b[i].p:=i; 136 my:=max(my,b[i].y); 137 end; 138 for i:=1 to n+m do 139 begin 140 next[i]:=last[b[i].x]; 141 last[b[i].x]:=i; 142 mx:=max(mx,b[i].x); 143 v[b[i].y]:=true; 144 v[my-b[i].y+1]:=true; 145 end; 146 p:=0; 147 for i:=1 to my do 148 begin 149 c[i]:=-inf; 150 if v[i] then 151 begin 152 inc(p); 153 g[i]:=p; 154 v[i]:=false; 155 end; 156 end; 157 fillchar(ans,sizeof(ans),127); 158 for i:=1 to mx do //这里只需要以x为第一关键字即可,因为计算贡献的时候会从四个方向算,总有一个会算到 159 begin 160 j:=last[i]; 161 while j<>0 do 162 begin 163 inc(t); 164 a[t]:=b[j]; 165 j:=next[j]; 166 end; 167 end; 168 t:=0; 169 for i:=1 to n+m do //先处理初始值对询问的影响 170 if (a[i].z=2) or (a[i].p<=n) then 171 begin 172 inc(t); 173 b[t]:=a[i]; 174 end; 175 176 work(1,t+1,1,1); 177 work(t,0,-1,1); 178 work(1,t+1,1,-1); 179 work(t,0,-1,-1); 180 t:=n; 181 for i:=1 to n+m do 182 if a[i].p>n then 183 begin 184 inc(t); 185 b[t]:=a[i]; 186 end; 187 188 for i:=n+1 to n+m do 189 a[i]:=b[i]; 190 191 cdq(n+1,n+m); //分治修改询问序列 192 for i:=1 to m do 193 if ans[i]<inf then writeln(ans[i]); 194 end.