蝗灾
单点修改,矩阵求和
n≤105 n ≤ 10 5
CDQ分治
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define File(x) "test."#x
#define For(i,s,e) for(int i=(s); i<=(e); i++)
#define Rep(i,s,e) for(int i=(s); i>=(e); i--)
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N=1000000+15;
struct Node{
int type,d,val,x,y;
/* bool operator < (const Node & o) const {
return x==o.x?y==o.y?type<o.type:y<o.y:x<o.x;
}*/
bool operator < (const Node &o) const
{
if(x!=o.x) return x<o.x;
else if(y!=o.y) return y<o.y;
else return type<o.type;
}
};
int w,n,tot,totx,ans[N];
Node a[N], b[N];
int bit[N];
void Modify(int p, int x){
while(p<=w){
bit[p]+=x; p+=lowbit(p);
}
}
int query(int p){
int ans=0;
while(p){
ans+=bit[p]; p-=lowbit(p);
}
return ans;
}
pair<int,int>move[N];
void CDQ(int l, int r){
if(l==r) return;
int mid=(l+r)>>1;
CDQ(l, mid); CDQ(mid+1, r);
int p1=l, p2=mid+1, cnt=l, num=0;
while(p1<=mid && p2<=r){
if(a[p1]<a[p2]){
if(a[p1].type==1){
Modify(a[p1].y, a[p1].val);
move[++num]=(pair<int,int>){a[p1].y, a[p1].val};
}
b[cnt++]=a[p1++];
} else {
if(a[p2].type==2) ans[a[p2].val]+=a[p2].d*query(a[p2].y);
b[cnt++]=a[p2++];
}
}
while(p2<=r){
if(a[p2].type==2) ans[a[p2].val]+=a[p2].d*query(a[p2].y);
b[cnt++]=a[p2++];
}
while(p1<=mid){
b[cnt++]=a[p1++];
}
For(i,1,num) Modify(move[i].first, -move[i].second);
For(i,l,r) a[i]=b[i];
}
int main()
{
freopen(File(in),"r",stdin);
freopen(File(out),"w",stdout);
scanf("%d%d",&w,&n);
For(i,1,n){
int opt, x_1, x_2, y_1, y_2, z;
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%d",&x_1,&y_1,&z);
a[++tot]=(Node){1, 1, z, x_1, y_1};
} else {
scanf("%d%d%d%d",&x_1,&y_1,&x_2,&y_2);
totx++;
a[++tot]=(Node){2, 1, totx, x_2, y_2};
a[++tot]=(Node){2, -1, totx, x_1-1, y_2};
a[++tot]=(Node){2, -1, totx, x_2, y_1-1};
a[++tot]=(Node){2, 1, totx, x_1-1, y_1-1};
//差分
}
}
CDQ(1,tot);
For(i,1,totx) printf("%d\n",ans[i]);
return 0;
}