题意就不讲了,挺好理解的。。暴力很好打。。 其实正解一眼看出来是线段树。。。 题目关键在于在 x 轴和 y 轴上,鱼的坐标变化都是单调的,因为 d 是正值。我们把在一个 矩形内部有多少个点的询问拆分成四个在某个点的左下角有多少个点的询问,然后用一棵线 段树维护鱼的 x 坐标,一棵线段树维护鱼的 y 坐标。对于移动操作,在对应的线段树上进行 区间更新,更新完成后询问该区间内的最大值,若最大值超过了我们关心的值,那么这个点 就可以删掉了,删除的方法可以通过在对应的线段树上把值设为-INF,同时继续询问直到 最大值不大于我们关心的值为止。那么我们就可以实时维护当前在我们关心的点左下角的点 有哪些了,这可以再借助于一个树状数组。这样子作四遍我们就能得到最终的答案了。 代码等一下在贴,,,正在调试。。 来了,,写的好长,,说实话A的时候一脸蒙蔽。。以为要调好久才能A。。结果蜜汁AC。。发现有人打了10000多b,orz
uses math; type tree=record maxx,maxy,sum:array[0..3]of int64; addx,addy:int64; end; const maxn=100100; inf=-2147483647; var x,y:array[0..4]of longint; ans:int64; typ,d,tl,tr1,n,m,t,xx1,xx2,yy1,yy2,i,j:longint; tx,ty:array[0..maxn]of longint; tr:array[0..maxn shl 2]of tree; procedure pushup(rt:longint); var i:longint; begin for i:=0 to 3 do begin tr[rt].maxx[i]:=max(tr[rt<<1].maxx[i],tr[rt<<1 or 1].maxx[i]); tr[rt].maxy[i]:=max(tr[rt<<1].maxy[i],tr[rt<<1 or 1].maxy[i]); tr[rt].sum[i]:=tr[rt<<1].sum[i]+tr[rt<<1 or 1].sum[i]; end; end; procedure pushdown(rt:longint); var i:longint; begin if(tr[rt].addx<>0)then begin tr[rt<<1].addx:=tr[rt<<1].addx+tr[rt].addx; inc(tr[rt<<1 or 1].addx,tr[rt].addx); for i:=0 to 3 do begin tr[rt<<1].maxx[i]:=tr[rt<<1].maxx[i]+tr[rt].addx; tr[rt<<1 or 1].maxx[i]:=tr[rt<<1 or 1].maxx[i]+tr[rt].addx; end; tr[rt].addx:=0; end; if(tr[rt].addy<>0)then begin inc(tr[rt<<1].addy,tr[rt].addy); inc(tr[rt<<1 or 1].addy,tr[rt].addy); for i:=0 to 3 do begin inc(tr[rt<<1].maxy[i],tr[rt].addy); inc(tr[rt<<1 or 1].maxy[i],tr[rt].addy); end; tr[rt].addy:=0; end; end; procedure build(l,r,rt:longint); var mid,i:longint; begin tr[rt].addy:=0; tr[rt].addx:=0; if(l=r)then begin for i:=0 to 3 do begin tr[rt].maxx[i]:=tx[l]; tr[rt].maxy[i]:=ty[l]; tr[rt].sum[i]:=1; end; exit; end; mid:=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1 or 1); pushup(rt); end; procedure update(l1,r1,rt,l,r:longint;v:int64;flag:longint); var mid,i:longint; begin if(l<=l1)and(r1<=r)then begin if(flag=0)then begin for i:=0 to 3 do inc(tr[rt].maxx[i],v); inc(tr[rt].addx,v); end else begin for i:=0 to 3 do inc(tr[rt].maxy[i],v); inc(tr[rt].addy,v); end; exit; end; pushdown(rt); mid:=(l1+r1)>>1; if(l<=mid)then update(l1,mid,rt<<1,l,r,v,flag); if(r>mid)then update(mid+1,r1,rt<<1 or 1,l,r,v,flag); pushup(rt); end; procedure adjust(l,r,rt:longint); var mid,i:longint; begin mid:=(l+r)>>1; for i:=0 to 3 do begin if(tr[rt].maxx[i]>x[i])or(tr[rt].maxy[i]>y[i])then begin if(l=r)then begin tr[rt].maxx[i]:=inf+1; tr[rt].maxy[i]:=inf+1; tr[rt].sum[i]:=0; continue; end; pushdown(rt); adjust(l,mid,rt<<1); adjust(mid+1,r,rt<<1 or 1); pushup(rt); end; end; end; function query(l1,r1,rt,l,r,f:longint):int64; var mid:longint; ans:int64; begin if(l<=l1)and(r1<=r)then exit(tr[rt].sum[f]); mid:=(l1+r1)>>1; ans:=0; if(l<=mid)then ans:=ans+query(l1,mid,rt<<1,l,r,f); if(r>mid)then ans:=ans+query(mid+1,r1,rt<<1 or 1,l,r,f); exit(ans); end; begin read(t); for j:=1 to t do begin readln(n); readln(xx1,yy1,xx2,yy2); x[0]:=xx2; y[0]:=yy2; x[1]:=xx1-1; y[1]:=yy2; x[2]:=xx2; y[2]:=yy1-1; x[3]:=xx1-1; y[3]:=yy1-1; for i:=1 to n do begin readln(tx[i],ty[i]); end; build(1,n,1); read(m); while m<>0 do begin read(typ); if(typ=1)then begin readln(tl,tr1,d); update(1,n,1,tl,tr1,int64(d),0); end; if(typ=2)then begin readln(tl,tr1,d); update(1,n,1,tl,tr1,int64(d),1); end; if(typ=3)then begin adjust(1,n,1); readln(tl,tr1); ans:=query(1,n,1,tl,tr1,0)-query(1,n,1,tl,tr1,1)-query(1,n,1,tl,tr1,2)+query(1,n,1,tl,tr1,3); writeln(ans); end; dec(m); end; end; end.