BZOJ1452: [JSOI2009]Count
【传送门:BZOJ1452】
简要题意:
给出一个n*m的矩阵,共有两种操作:
1 x y c将第x行第y列的数改为c
2 x1 x2 y1 y2 c求出第x1行第y1列到第x2行第y2列值为c的格子数
题解:
第一次写二维树状数组,和一维差不多
a[x][y][c]表示第1行第1列到第x行第y列值为c的格子数
然后维护树状数组,求值时,要用矩阵的思想来求
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int a[310][310][110]; int n,m; int lowbit(int x){return x&-x;} void change(int x,int y,int c,int d) { int t=y; while(x<=n) { y=t; while(y<=m) { a[x][y][c]+=d; y+=lowbit(y); } x+=lowbit(x); } } int getsum(int x,int y,int c) { int ans=0,t=y; while(x!=0) { y=t; while(y!=0) { ans+=a[x][y][c]; y-=lowbit(y); } x-=lowbit(x); } return ans; } int map[310][310]; int main() { scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&map[i][j]); change(i,j,map[i][j],1); } } int q; scanf("%d",&q); while(q--) { int t; scanf("%d",&t); if(t==1) { int x,y,c; scanf("%d%d%d",&x,&y,&c); change(x,y,map[x][y],-1); map[x][y]=c; change(x,y,c,1); } else { int x1,x2,y1,y2,c; scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c); printf("%d\n",getsum(x2,y2,c)-getsum(x1-1,y2,c)-getsum(x2,y1-1,c)+getsum(x1-1,y1-1,c)); } } return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚