题意就不讲了,挺好理解的。。暴力很好打。。
其实正解一眼看出来是线段树。。。
题目关键在于在 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.