命令 |
参数限制 |
内容 |
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分治+树状数组,同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; }