n,m<=300,n*m的一个矩阵,q<=200000个操作:修改某个点权值;查询某个矩形范围内某个权值有多少个点。权值<=100。
二维树状数组的模板!
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 //#include<math.h> 5 #include<algorithm> 6 //#include<iostream> 7 using namespace std; 8 9 int n,m; 10 #define maxn 311 11 struct BIT 12 { 13 int a[maxn][maxn]; 14 BIT() {memset(a,0,sizeof(a));} 15 void add(int x,int y,int v) 16 { 17 for (int i=x;i<=n;i+=i&-i) 18 for (int j=y;j<=m;j+=j&-j) 19 a[i][j]+=v; 20 } 21 int query(int x,int y) 22 { 23 int ans=0; 24 for (int i=x;i;i-=i&-i) 25 for (int j=y;j;j-=j&-j) 26 ans+=a[i][j]; 27 return ans; 28 } 29 }t[103]; 30 int q,x,y,z,w,v,a[maxn][maxn]; 31 int main() 32 { 33 scanf("%d%d",&n,&m); 34 for (int i=1;i<=n;i++) 35 for (int j=1;j<=m;j++) 36 { 37 scanf("%d",&a[i][j]); 38 t[a[i][j]].add(i,j,1); 39 } 40 scanf("%d",&q); 41 while (q--) 42 { 43 scanf("%d",&x); 44 if (x==1) 45 { 46 scanf("%d%d%d",&x,&y,&v); 47 t[a[x][y]].add(x,y,-1); 48 t[(a[x][y]=v)].add(x,y,1); 49 } 50 else 51 { 52 scanf("%d%d%d%d%d",&x,&y,&w,&z,&v); 53 printf("%d\n",t[v].query(y,z)-t[v].query(x-1,z)-t[v].query(y,w-1)+t[v].query(x-1,w-1)); 54 } 55 } 56 return 0; 57 }