2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 738 Solved: 307
[ 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分治+树状数组,同bzoj1176。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 500005
#define maxm 800005
using namespace std;
int n,cnt,tot;
int ans[maxn],c[maxn];
struct data{int flag,x,y,v,pos,id;}a[maxm],b[maxm];
inline 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*10+ch-'0';ch=getchar();}
return x*f;
}
inline bool cmp(data a,data b)
{
if (a.x!=b.x) return a.x<b.x;
return a.pos<b.pos;
}
inline void add(int x,int y)
{
for(;x<=n;x+=(x&(-x))) c[x]+=y;
}
inline int query(int x)
{
int ret=0;
for(;x;x-=(x&(-x))) ret+=c[x];
return ret;
}
inline void solve(int l,int r)
{
if (l>=r) return;
int mid=(l+r)>>1,l1=l,l2=mid+1;
F(i,l,r)
{
if (a[i].flag==1&&a[i].pos<=mid) add(a[i].y,a[i].v);
if (a[i].flag==2&&a[i].pos>mid) ans[a[i].id]+=a[i].v*query(a[i].y);
}
F(i,l,r) if (a[i].flag==1&&a[i].pos<=mid) add(a[i].y,-a[i].v);
F(i,l,r)
{
if (a[i].pos<=mid) b[l1++]=a[i];
else b[l2++]=a[i];
}
F(i,l,r) a[i]=b[i];
solve(l,mid);solve(mid+1,r);
}
int main()
{
n=read();
int opt=read();
while (opt!=3)
{
if (opt==1)
{
int x=read(),y=read(),v=read();
cnt++;a[cnt]=(data){1,x,y,v,cnt,0};
}
else
{
int x1=read()-1,y1=read()-1,x2=read(),y2=read();
tot++;
cnt++;a[cnt]=(data){2,x1,y1,1,cnt,tot};
cnt++;a[cnt]=(data){2,x2,y2,1,cnt,tot};
cnt++;a[cnt]=(data){2,x1,y2,-1,cnt,tot};
cnt++;a[cnt]=(data){2,x2,y1,-1,cnt,tot};
}
opt=read();
}
sort(a+1,a+cnt+1,cmp);
solve(1,cnt);
F(i,1,tot) printf("%d\n",ans[i]);
return 0;
}