bzoj 1452 二维树状数组
每一种颜色存一颗二维树状数组,然后直接做就行了。
/************************************************************** Problem: 1452 User: BLADEVIL Language: C++ Result: Accepted Time:4844 ms Memory:36904 kb ****************************************************************/ //By BLADEVIL #include <cstdio> #include <cstring> #define maxn 301 #define maxc 101 using namespace std; int map[maxn][maxn]; int n,m,task; struct rec{ int c[maxn][maxn]; rec(){memset(c,0,sizeof c);} void change(int i,int j,int d){ for (int x=i;x<=n;x+=x&-x) for (int y=j;y<=m;y+=y&-y) c[x][y]+=d; } int sum(int i,int j){ int ans=0; for (int x=i;x;x-=x&-x) for (int y=j;y;y-=y&-y) ans+=c[x][y]; return ans; } int sum(int x,int y,int xx,int yy){ return sum(xx,yy)-sum(x-1,yy)-sum(xx,y-1)+sum(x-1,y-1); } } w[maxc]; void change(int x,int y,int z){ int k=map[x][y]; w[k].change(x,y,-1); w[z].change(x,y,1); map[x][y]=z; } int main(){ int x,y,xx,yy,z; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&map[i][j]),w[map[i][j]].change(i,j,1); scanf("%d",&task); while (task--){ int k; scanf("%d",&k); if (k==1){ scanf("%d%d%d",&x,&y,&z); change(x,y,z); } else { scanf("%d%d%d%d%d",&x,&xx,&y,&yy,&z); printf("%d\n",w[z].sum(x,y,xx,yy)); } } return 0; }