[BZOJ]2683: 简单题 CDQ分治+树状数组

来源:互联网 发布:相册加密软件 编辑:程序博客网 时间:2024/05/19 18:47

Description
你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:
命令
参数限制
内容
1 x y A
1<=x,y<=N,A是正整数
将格子x,y里的数字加上A
2 x1 y1 x2 y2
1<=x1<= x2<=N
1<=y1<= y2<=N
输出x1 y1 x2 y2这个矩形内的数字和
3

终止程序

题解:

CDQ分治直接上就行了,注意最后两句话的顺序……

代码:

#include<bits/stdc++.h>using namespace std;#define LL long long#define pa pair<int,int>const int Maxn=500010;const int Maxm=200010;const int inf=2147483647;int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();    return x*f;}//1 修改 2 减 3 加 struct Opt{int px,py,x,type;}q[Maxm<<2],temp[Maxm<<2];bool operator < (Opt a,Opt b){    if(a.px!=b.px)return a.px<b.px;    if(a.py!=b.py)return a.py<b.py;    return a.type<b.type;}int n,m=0,cnt=0,cntq=0,num[Maxm];LL ans[Maxm],s[Maxn];void add(int x,LL y){for(;x<=n;x+=(x&-x))s[x]+=y;}LL getsum(int x){LL re=0;for(;x;x-=(x&-x))re+=s[x];return re;}void solve(int l,int r){    if(l==r)return;    int mid=l+r>>1;    solve(l,mid);solve(mid+1,r);    int i=l,j=mid+1,len=0,o=0;    while(i<=mid&&j<=r)    {        if(q[i].px<q[j].px||(q[i].px==q[j].px&&q[i].type<q[j].type))        {            if(q[i].type==1)add(q[i].py,(LL)(q[i].x)),num[++o]=i;            temp[++len]=q[i++];        }        else        {            if(q[j].type==2)ans[q[j].x]-=getsum(q[j].py);            else if(q[j].type==3)ans[q[j].x]+=getsum(q[j].py);            temp[++len]=q[j++];        }    }    while(i<=mid)temp[++len]=q[i++];    while(j<=r)    {        if(q[j].type==2)ans[q[j].x]-=getsum(q[j].py);        else if(q[j].type==3)ans[q[j].x]+=getsum(q[j].py);        temp[++len]=q[j++];    }    for(int p=1;p<=o;p++)add(q[num[p]].py,(LL)(-q[num[p]].x));    for(int p=1;p<=len;p++)q[l+p-1]=temp[p];}int main(){    n=read();    int op=read();    while(op!=3)    {        m++;        int x=read(),y=read(),x1,y1;        if(op==1)        {            q[++cnt].x=read();q[cnt].type=1;            q[cnt].px=x;q[cnt].py=y;        }        else        {            x1=read(),y1=read();            q[++cnt].px=x-1;q[cnt].py=y-1;q[cnt].type=3;            q[++cnt].px=x1;q[cnt].py=y1;q[cnt].type=3;            q[++cnt].px=x1;q[cnt].py=y-1;q[cnt].type=2;            q[++cnt].px=x-1;q[cnt].py=y1;q[cnt].type=2;            cntq++;            for(int i=cnt-3;i<=cnt;i++)q[i].x=cntq;        }        op=read();    }    solve(1,cnt);    for(int i=1;i<=cntq;i++)printf("%lld\n",ans[i]);}
原创粉丝点击