命令 |
参数限制 |
内容 |
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
#include
#include
#include
#include
#include
#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=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;
}