对每个颜色开一个二维树状数组。
时间复杂度O(qlognlogm),空间复杂度O(cnm)。
#include<cstdio>
#include<cstring>
int map[310][310],s[110][310][310],n,m;
void add(int p,int x,int y,int k)
{
for (int i=x;i<=n;i+=i&-i)
for (int j=y;j<=m;j+=j&-j)
s[p][i][j]+=k;
}
int qry(int p,int x,int y)
{
int ret=0;
for (int i=x;i;i-=i&-i)
for (int j=y;j;j-=j&-j)
ret+=s[p][i][j];
return ret;
}
int main()
{
int i,j,k,p,q,x,y,z,x1,x2,y1,y2,T;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
add(map[i][j],i,j,1);
}
scanf("%d",&T);
while (T--)
{
scanf("%d",&q);
if (q==1)
{
scanf("%d%d%d",&x,&y,&z);
add(map[x][y],x,y,-1);
map[x][y]=z;
add(z,x,y,1);
}
else
{
scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&z);
printf("%d\n",qry(z,x2,y2)-qry(z,x2,y1-1)-qry(z,x1-1,y2)+qry(z,x1-1,y1-1));
}
}
}