【BZOJ1452】【JSOI2009】count

暴力出奇迹……
原题:

图片题面好评(图片样例差评

【BZOJ1452】【JSOI2009】count

【BZOJ1452】【JSOI2009】count

我最开始的思路:

容斥,变成每次询问((1,1),(x,y))这个矩阵中颜色为c的个数,然后三维偏序!cdq分治!

但是2e5的询问好像并不大丈夫?乘个4就变成8e5了

然后搜题解……woc原来还可以这么玩……

因为每次值查询一个值所以直接开100个树状数组xjb搞就行了,复杂度没问题

那么如果把询问减小,然后每次询问的是一个区间的值要怎么做呢嘿嘿嘿

代码:

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int rd(){int z=,mk=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mk=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mk;
}
int n,m,quq,a[][];
int e[][][],lbt[];
void gtlbt(){ for(int i=;i<=;++i) lbt[i]=i&-i;}
void mdf(int x,int y,int z,int v){
for(int i=x;i<=n;i+=lbt[i])for(int j=y;j<=m;j+=lbt[j])
e[z][i][j]+=v;
}
int qr(int x,int y,int z){
int bwl=;
for(int i=x;i;i-=lbt[i])for(int j=y;j;j-=lbt[j])
bwl+=e[z][i][j];
return bwl;
}
int main(){//freopen("ddd.in","r",stdin);
//freopen("ddd.out","w",stdout);
gtlbt();
cin>>n>>m;
for(int i=;i<=n;++i)for(int j=;j<=m;++j)
mdf(i,j,a[i][j]=rd(),);
int mk,x1,y1,x2,y2,v,bwl=;
cin>>quq;
while(quq--){
mk=rd();
if(mk==){
x1=rd(),y1=rd(),v=rd();
mdf(x1,y1,a[x1][y1],-),mdf(x1,y1,a[x1][y1]=v,);
}
else{
x1=rd(),x2=rd(),y1=rd(),y2=rd(),v=rd();
bwl=qr(x1-,y1-,v)+qr(x2,y2,v);
bwl-=qr(x1-,y2,v)+qr(x2,y1-,v);
printf("%d\n",bwl);
}
}
return ;
}
上一篇:SQL语言知识点总结


下一篇:BeautifulSoup搜索文档