577. 蝗灾

★★★☆   输入文件:

​locust.in​​   输出文件:

​locust.out​​   

简单对比

时间限制:2 s   内存限制:128 MB


DESCRIPTION
C国国土辽阔,地大物博......但是最近却在闹蝗灾.....
我们可以把C国国土当成一个W×W的矩阵,你会收到一些诸如(X,Y,Z)的信息,代表(X,Y)这个点增多了
Z只蝗虫,而由于C国政府机关比较臃肿,为了批复消灭蝗虫的请求需要询问一大堆的问题......每个询问形如
(X1,Y1,X2,Y2),询问在(X1,Y1,X2,Y2)范围内有多少蝗虫(请注意询问不会改变区域内的蝗虫数),
你作为一个C国的程序员,需要编一个程序快速的回答所有的询问。

NOTICE
C国一开始没有蝗虫。

INPUT
输入文件的第一行包括一个整数W,代表C国国土的大小。第二行有一个整数N,表示事件数。接下来有N行表示N个事件,以(1 X Y Z)的形式或(2,X1,Y1,X2,Y2)的形式给出,分别代表蝗虫的增加和询问。

OUTPUT
对于每个询问输出一个整数表示需要的结果。

SAMPLE INPUT
locust.in
5
8
2 4 1 4 2
1 3 1 8
1 4 4 4
2 1 3 4 4
1 1 5 1
1 4 4 5
2 2 2 5 4
2 3 2 4 4

SAMPLE OUTPUT
locust.out
0
4
9
9

数据范围:
10%的数据满足W<=100,N<=100;
30%的数据满足W<=2000,N<=5000;
50%的数据满足W<=100000,N<=50000;
100%的数据满足W<=500000,N<=200000,每次蝗虫增加数不超过1000;

时间限制:

2s





【分析】

复习一下CDQ

三倍经验了...


【代码】

//cogs 577 蝗灾
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=800005;
int tot,n,m,T,id;
int c[mxn],t[mxn],ans[mxn];
inline int lowbit(int x) {return x&-x;}
inline void add(int x,int v) {for(int i=x;i<=n;i+=lowbit(i)) c[i]+=v;}
inline int getsum(int x) {int sum=0;for(int i=x;i>=1;i-=lowbit(i)) sum+=c[i];return sum;}
struct query
{
int x,y,f,opt,be,id;
}q[mxn],tmp[mxn];
inline bool comp(query a,query b)
{
if(a.x==b.x && a.y==b.y) return a.be<b.be;
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
inline void CDQ(int l,int r)
{
int i,j,mid=l+r>>1,l1=l,l2=mid+1;
if(l==r) return;
fo(i,l,r)
{
if(q[i].id<=mid && q[i].opt==1) add(q[i].y,q[i].f);
if(q[i].id>mid && q[i].opt==2) ans[q[i].be]+=q[i].f*getsum(q[i].y);
}
fo(i,l,r) if(q[i].id<=mid && q[i].opt==1) add(q[i].y,-q[i].f);
fo(i,l,r)
if(q[i].id<=mid) tmp[l1++]=q[i];
else tmp[l2++]=q[i];
fo(i,l,r) q[i]=tmp[i];
CDQ(l,mid),CDQ(mid+1,r);
}
int main()
{
freopen("locust.in","r",stdin);
freopen("locust.out","w",stdout);
int i,j,x1,y1,x2,y2,opt;
scanf("%d%d",&n,&m);
fo(i,1,m)
{
scanf("%d",&opt);
if(opt==1) q[++tot].opt=1,scanf("%d%d%d",&q[tot].x,&q[tot].y,&q[tot].f),q[tot].be=i,q[tot].id=++id;
else
{
t[i]=1;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
q[++tot].opt=2,q[tot].x=x1-1,q[tot].y=y1-1,q[tot].f=1,q[tot].be=i,q[tot].id=++id;
q[++tot].opt=2,q[tot].x=x2,q[tot].y=y1-1,q[tot].f=-1,q[tot].be=i,q[tot].id=++id;
q[++tot].opt=2,q[tot].x=x1-1,q[tot].y=y2,q[tot].f=-1,q[tot].be=i,q[tot].id=++id;
q[++tot].opt=2,q[tot].x=x2,q[tot].y=y2,q[tot].f=1,q[tot].be=i,q[tot].id=++id;
}
}
sort(q+1,q+tot+1,comp);
CDQ(1,tot);
fo(i,1,m) if(t[i]) printf("%d\n",ans[i]);
return 0;
}