标签:
题意:
n*m矩阵,支持两个操作,修改某个格子权值和查询某个子矩阵特定权值出现次数。n,m≤300,权值为1到100的整数。
题解:
原来二维前缀和也可以用树状数组维护,只要那个不断增加/减少lowbit的循环再嵌套一层就行了。同时因为权值是1到100的整数,所以二维前缀和多一维维护特定权值个数就行了。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 301 5 #define inc(i,j,k) for(int i=j;i<=k;i++) 6 #define lb(x) x&-x 7 using namespace std; 8 9 int sm[maxn][maxn][maxn/3+1],col[maxn][maxn],n,m; 10 void update(int x,int y,int z,int v){ 11 for(int i=x;i<=n;i+=lb(i))for(int j=y;j<=m;j+=lb(j))sm[i][j][z]+=v; 12 } 13 int query(int x,int y,int z){ 14 int q=0; for(int i=x;i>=1;i-=lb(i))for(int j=y;j>=1;j-=lb(j))q+=sm[i][j][z]; return q; 15 } 16 inline int read(){ 17 char ch=getchar(); int f=1,x=0; 18 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar(); 19 return f*x; 20 } 21 int main(){ 22 n=read(); m=read(); inc(i,1,n)inc(j,1,m){col[i][j]=read(); update(i,j,col[i][j],1);} int q=read(); 23 inc(i,1,q){ 24 int x=read(); 25 if(x==1){ 26 int x0=read(),x1=read(),x2=read(); 27 update(x0,x1,col[x0][x1],-1); update(x0,x1,x2,1); col[x0][x1]=x2; 28 } 29 if(x==2){ 30 int x1=read(),x2=read(),y1=read(),y2=read(),c=read(); 31 printf("%d\n",query(x2,y2,c)-query(x1-1,y2,c)-query(x2,y1-1,c)+query(x1-1,y1-1,c)); 32 } 33 } 34 return 0; 35 }
20160603
标签:
原文地址:http://www.cnblogs.com/YuanZiming/p/5689536.html