火神的鱼

来源:互联网 发布:免费听音乐的软件 编辑:程序博客网 时间:2024/04/30 21:00

Description

火神最爱的就是吃鱼了,所以某一天他来到了一个池塘边捕鱼。池塘可以看成一个二维的平面,而他的渔网可以看成一个与坐标轴平行的矩形。
池塘里的鱼不停地在水中游动,可以看成一些点。有的时候会有鱼游进渔网,有的时候也会有鱼游出渔网。所以火神不知道什么时候收网才可以抓住最多的鱼,现在他寻求你的帮助。
他对池塘里的每条鱼都给予了一个标号,分别从1到n标号,n表示池塘里鱼的总数。鱼的游动可以概括为两个动作:
1 l r d : 表示标号在[l,r]这个区间内的鱼向x轴正方向游动了d个单位长度。
2 l r d:表示标号在[l,r]这个区间内的鱼向y轴正方向游动了d个单位长度。
在某些时刻火神会询问你现在有多少条他关心的鱼在渔网内(边界上的也算),请你来帮助他吧。

Solution

题目简意是一些点在坐标轴的第一象限,且只会朝正方向移动,给出一个矩阵,问在若干次操作后,标号在[l,r]这个区间内的鱼有多少条在矩阵中。对于四个点,每个点开两棵线段树,一棵维护横坐标,另一棵维护纵坐标,而且只维护左下角的点的信息。因为每个点只会向正方向移动,所以一个点只会退出线段树一次,所以很好维护,计算答案只需要用好像矩阵前缀和的计算就好了。

Code

var    mj:array[1..2,1..4] of longint=((1,3,5,7),(2,4,6,8));    w:array[1..8] of longint;    s:array[1..4] of longint;    tr,bz,ans:array[1..8,1..100000] of longint;    fx,fy:array[1..30000] of longint;    t,n,m,i,cz,l,r,d,x,y,sum:longint;function max(x,y:longint):longint;begin    if x>y then exit(x) else exit(y);end;procedure make(bh,l,r,wz:longint);var mid:longint;begin    if l=r then    begin        case bh mod 2 of            1:begin                  tr[bh,wz]:=fx[l];                  ans[bh,wz]:=1;                  bz[bh,wz]:=0;              end;            0:begin                  tr[bh,wz]:=fy[l];                  ans[bh,wz]:=1;                  bz[bh,wz]:=0;              end;        end;        exit;    end;    mid:=(l+r)div 2;    make(bh,l,mid,wz*2);    make(bh,mid+1,r,wz*2+1);    tr[bh,wz]:=max(tr[bh,wz*2],tr[bh,wz*2+1]);    ans[bh,wz]:=ans[bh,wz*2]+ans[bh,wz*2+1];end;procedure down(bh,l,r,wz:longint);begin    if bz[bh,wz]=0 then exit;    tr[bh,wz*2]:=tr[bh,wz*2]+bz[bh,wz];    tr[bh,wz*2+1]:=tr[bh,wz*2+1]+bz[bh,wz];    bz[bh,wz*2]:=bz[bh,wz*2]+bz[bh,wz];    bz[bh,wz*2+1]:=bz[bh,wz*2+1]+bz[bh,wz];    bz[bh,wz]:=0;end;procedure change(bh,l,r,wz,x,y,z:longint);var mid:longint;begin    if (l=x)and(r=y) then    begin        tr[bh,wz]:=tr[bh,wz]+z;        bz[bh,wz]:=bz[bh,wz]+z;        exit;    end;    down(bh,l,r,wz);    mid:=(l+r)div 2;    if x>mid then change(bh,mid+1,r,wz*2+1,x,y,z)    else if y<=mid then change(bh,l,mid,wz*2,x,y,z)    else    begin        change(bh,l,mid,wz*2,x,mid,z);        change(bh,mid+1,r,wz*2+1,mid+1,y,z);    end;    tr[bh,wz]:=max(tr[bh,wz*2],tr[bh,wz*2+1]);    ans[bh,wz]:=ans[bh,wz*2]+ans[bh,wz*2+1];end;procedure del(bh,l,r,wz:longint);var mid:longint;begin    if l=r then    begin        tr[bh,wz]:=-maxlongint;        ans[bh,wz]:=0;        sum:=l;        exit;    end;    down(bh,l,r,wz);    mid:=(l+r)div 2;    if tr[bh,wz*2]<tr[bh,wz*2+1] then del(bh,mid+1,r,wz*2+1)       else del(bh,l,mid,wz*2);    tr[bh,wz]:=max(tr[bh,wz*2],tr[bh,wz*2+1]);    ans[bh,wz]:=ans[bh,wz*2]+ans[bh,wz*2+1];end;procedure del1(bh,l,r,wz,x:longint);var mid:longint;begin    if l=r then    begin        tr[bh,wz]:=-maxlongint;        ans[bh,wz]:=0;        exit;    end;    down(bh,l,r,wz);    mid:=(l+r)div 2;    if x>mid then del1(bh,mid+1,r,wz*2+1,x)       else del1(bh,l,mid,wz*2,x);    tr[bh,wz]:=max(tr[bh,wz*2],tr[bh,wz*2+1]);    ans[bh,wz]:=ans[bh,wz*2]+ans[bh,wz*2+1];end;procedure ask(bh,l,r,wz,x,y,z:longint);var mid:longint;begin    if (l=x)and(r=y) then    begin        s[z]:=s[z]+ans[bh,wz];        exit;    end;    down(bh,l,r,wz);    mid:=(l+r)div 2;    if x>mid then ask(bh,mid+1,r,wz*2+1,x,y,z)    else if y<=mid then ask(bh,l,mid,wz*2,x,y,z)    else    begin        ask(bh,l,mid,wz*2,x,mid,z);        ask(bh,mid+1,r,wz*2+1,mid+1,y,z);    end;end;procedure cz1;var i:longint;begin    readln(l,r,d);    for i:=1 to 4 do    begin        change(mj[1,i],1,n,1,l,r,d);        while tr[mj[1,i],1]>w[mj[1,i]] do        begin            del(mj[1,i],1,n,1);            del1(mj[2,i],1,n,1,sum);        end;    end;end;procedure cz2;var i:longint;begin    readln(l,r,d);    for i:=1 to 4 do    begin        change(mj[2,i],1,n,1,l,r,d);        while tr[mj[2,i],1]>w[mj[2,i]] do        begin            del(mj[2,i],1,n,1);            del1(mj[1,i],1,n,1,sum);        end;    end;end;procedure cz3;begin    readln(l,r);    fillchar(s,sizeof(s),0);    ask(3,1,n,1,l,r,1);    ask(1,1,n,1,l,r,2);    ask(7,1,n,1,l,r,3);    ask(5,1,n,1,l,r,4);    writeln(s[1]-s[2]-s[3]+s[4]);end;begin    readln(t);    while t>0 do    begin        dec(t);        fillchar(tr,sizeof(tr),0);        fillchar(ans,sizeof(ans),0);        fillchar(bz,sizeof(bz),0);        readln(n);        read(x,y);        w[5]:=x;w[6]:=y;        w[1]:=x;w[8]:=y;        read(x,y);        w[3]:=x;w[4]:=y;        w[7]:=x;w[2]:=y;        dec(w[1]);dec(w[5]);dec(w[6]);dec(w[8]);        for i:=1 to n do readln(fx[i],fy[i]);        for i:=1 to 8 do make(i,1,n,1);        for i:=1 to 4 do            while tr[mj[1,i],1]>w[mj[1,i]] do            begin                del(mj[1,i],1,n,1);                del1(mj[2,i],1,n,1,sum);            end;        for i:=1 to 4 do            while tr[mj[2,i],1]>w[mj[2,i]] do            begin                del(mj[2,i],1,n,1);                del1(mj[1,i],1,n,1,sum);            end;        readln(m);        for i:=1 to m do        begin            read(cz);            case cz of                1:cz1;                2:cz2;                3:cz3;            end;        end;    end;end.
0 0
原创粉丝点击