题目链接:戳这里
2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1877 Solved: 762
[ Submit][ Status][ Discuss]
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 |
无 |
终止程序 |
Input
输入文件第一行一个正整数N。
接下来每行一个操作。
Output
对于每个2操作,输出一个对应的答案。
Sample Input
4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
5
HINT
1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
于是考虑cdq分治,但我cdq分治实在是太菜了,只能给出按照什么排序QAQ。
对于每个询问,按(x,y,opt)排序。
正常的cdq分治即可,用树状数组维护答案。
代码:
#include<bits/stdc++.h>
#define maxn 200005
#define maxm 500005
#define Q q[tot]
using namespace std;
typedef long long LL;
int read()
{
char c;int sum=0,f=1;c=getchar();
while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}
return sum*f;
}
int n,tot,t;
int c[maxm],ans[maxn];
void add(int x,int v){for(;x<=n;x+=x&(-x))c[x]+=v;}
int sum(int x){int ret=0;for(;x;x-=x&(-x))ret+=c[x];return ret;}
struct node{
int opt,x,y,val,id,bel;
}q[maxn<<2],tmp[maxn<<2];
bool cmp(node a,node b)
{
if(a.x==b.x)
{
if(a.y==b.y)
return a.opt<b.opt;
return a.y<b.y;
}
return a.x<b.x;
}
void cdq(int l,int r)
{
if(l==r) return;
int mid=l+r>>1;
for(int i=l;i<=r;i++)
{
if(q[i].opt==1 && q[i].id<=mid) add(q[i].y,q[i].val);
if(q[i].opt==2 && q[i].id>mid) ans[q[i].bel]+=sum(q[i].y)*q[i].val;
}
for(int i=l;i<=r;i++)
if(q[i].opt==1 && q[i].id<=mid) add(q[i].y,-q[i].val);
int l1=l,l2=mid+1;
for(int i=l;i<=r;i++)
{
if(q[i].id<=mid)
tmp[l1++]=q[i];
else tmp[l2++]=q[i];
}
for(int i=l;i<=r;i++)
q[i]=tmp[i];
cdq(l,mid);cdq(mid+1,r);
}
int main()
{
n=read();
while(1)
{
int op=read();
if(op==3) break;
if(op==1)
{
q[++tot].opt=1;Q.x=read();Q.y=read();Q.val=read();Q.id=tot;
}
else
{
int X1=read(),Y1=read(),X2=read(),Y2=read();
q[++tot].opt=2,Q.x=X1-1,Q.y=Y1-1,Q.val=1,Q.id=tot,Q.bel=++t;
q[++tot].opt=2,Q.x=X1-1,Q.y=Y2,Q.val=-1,Q.id=tot,Q.bel=t;
q[++tot].opt=2,Q.x=X2,Q.y=Y1-1,Q.val=-1,Q.id=tot,Q.bel=t;
q[++tot].opt=2,Q.x=X2,Q.y=Y2,Q.val=1,Q.id=tot,Q.bel=t;
}
}
sort(q+1,q+1+tot,cmp);
cdq(1,tot);
for(int i=1;i<=t;i++)
printf("%d\n",ans[i]);
return 0;
}