bzoj2716

感人肺腑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]then writeln(ans[i]);
194 end.
View Code

 

转载于:https://www.cnblogs.com/phile/p/4472944.html

你可能感兴趣的:(bzoj2716)