传送门
发现颜色数超级少。
然后我们对于每一个颜色维护一个二维树状数组就水过辣。
#include<cstring>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#define inf 2100000000
#define N 105
using namespace std;
int n,m,p,x,y,c,xx,yy;
int a[305][305],b[105][305][305];
inline int read(){
int k=0;
char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar());
for (;ch>='0'&&ch<='9';ch=getchar()) k=k*10+ch-48;
return k;
}
inline void change(int x,int y,int c,int u){
for (int i=x;i<=n;i+=i&(-i))
for (int j=y;j<=m;j+=j&(-j)) b[c][i][j]+=u;
}
inline int ask(int x,int y,int c){
int s=0;
for (int i=x;i;i-=i&(-i))
for (int j=y;j;j-=j&(-j)) s+=b[c][i][j];
return s;
}
int main(){
n=read();
m=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
a[i][j]=read();
change(i,j,a[i][j],1);
}
p=read();
for (int i=1;i<=p;i++){
x=read();
if (x==1){
x=read();
y=read();
c=read();
change(x,y,a[x][y],-1);
change(x,y,c,1);
a[x][y]=c;
}
else{
x=read();
xx=read();
y=read();
yy=read();
c=read();
printf("%d\n",ask(xx,yy,c)-ask(x-1,yy,c)-ask(xx,y-1,c)+ask(x-1,y-1,c));
}
}
}