C93 二维树状数组 P4054 [JSOI2009] 计数问题
视频链接:C93 二维树状数组 P4054 [JSOI2009] 计数问题_哔哩哔哩_bilibili
//100个二维树状数组 点修+区查 O(n*n*logn*logn+q*logn*logn) #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define lowb(x) x&-x int n,m; int a[301][301]; //格子的权值 int s[301][301][101]; //各权值在矩阵中出现的次数 void change(int x,int y,int c,int v){ //向后修 for(int i=x;i<=n;i+=lowb(i)) for(int j=y;j<=m;j+=lowb(j)) s[i][j][c]+=v; } int query(int x,int y,int c){ //向前查 int t=0; for(int i=x;i;i-=lowb(i)) for(int j=y;j;j-=lowb(j)) t+=s[i][j][c]; return t; } int main(){ int x1,y1,x2,y2,c,Q,op,ans; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ scanf("%d",&c); a[i][j]=c; change(i,j,c,1); } scanf("%d",&Q); while(Q--){ scanf("%d",&op); if(op == 1){ //修改: 先减后加 scanf("%d%d%d",&x1,&y1,&c); change(x1,y1,a[x1][y1],-1); a[x1][y1]=c; change(x1,y1,c,1); } else{ //查询: 二维区间和 scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c); ans=query(x2,y2,c)-query(x1-1,y2,c) -query(x2,y1-1,c)+query(x1-1,y1-1,c); printf("%d\n",ans); } } }
//100个二维树状数组 点修+区查 O(n*n*logn*logn+q*logn*logn) #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define lowb(x) x&-x int n,m; int a[301][301]; //格子的权值 struct T{ int s[301][301]; //各权值在矩阵中出现的次数 void change(int x,int y,int k){ //向后修 for(int i=x;i<=n;i+=lowb(i)) for(int j=y;j<=m;j+=lowb(j)) s[i][j]+=k; } int query(int x,int y){ //向前查 int t=0; for(int i=x;i;i-=lowb(i)) for(int j=y;j;j-=lowb(j)) t+=s[i][j]; return t; } }c[101]; void add(int x,int y,int v,int k){ //点加 c[v].change(x,y,k); } int sum(int x1,int y1,int x2,int y2,int v){ //区间和 return c[v].query(x2,y2)-c[v].query(x1-1,y2) -c[v].query(x2,y1-1)+c[v].query(x1-1,y1-1); } int main(){ int x1,y1,x2,y2,v,Q,op,ans; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ scanf("%d",&v); a[i][j]=v; add(i,j,v,1); } scanf("%d",&Q); while(Q--){ scanf("%d",&op); if(op == 1){ //修改: 先减后加 scanf("%d%d%d",&x1,&y1,&v); add(x1,y1,a[x1][y1],-1); a[x1][y1]=v; add(x1,y1,v,1); } else{ //查询: 二维区间和 scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&v); printf("%d\n",sum(x1,y1,x2,y2,v)); } } }