Matrix POJ 2155 Matrix
学习二维树状数组,线段树:
题意: 给定一个n*n的0-1矩阵,执行一些如下的两种操作:C a,b,c,d :将矩阵中(a,b)到(c,d)的格子中的0-1进行“非”操作Q a b :询问当前(a,b)位置的元素的值二维树状数组
转化成:单点更新,成段求和。
一种思路是用一个二维数组tree[][]来标记数组中值的变换次数,通过变 换的次数就可以得出当前数组元素的值了。我们可以先分析一下一维时候的情况,假设一个一维的数组array[] ,现在要求给区间[a,b]内的每个元素增加一个值add,我们可以这样利用树状数组,将a元素增加add值,将(b+1)元素增加一个-add值,接下 去每次询问k位置的值的时候,只要将1-k位置的所有元素的值相加就是最后k位置的元素的值(PS:一开始元素的所有值都是0)。
View Code
1 #include<stdio.h> 2 #include<string.h> 3 #define size 1005 4 int tree[size][size]; 5 int x,n,t; 6 int lowbit(int k){ 7 return k&(-k); 8 } 9 10 void add(int x,int y,int d){ 11 int j; 12 while(x<=n){ 13 j=y; 14 while(j<=n){ 15 tree[x][j]+=d; 16 j+=lowbit(j); 17 } 18 x+=lowbit(x); 19 } 20 } 21 22 int gsum(int x,int y){ 23 int j,res=0; 24 while(x>0){ 25 j=y; 26 while(j>0){ 27 res+=tree[x][j]; 28 j-=lowbit(j); 29 } 30 x-=lowbit(x); 31 } 32 return res; 33 } 34 35 int main() 36 { 37 int x1,y1,x2,y2; 38 char s[3]; 39 // freopen("test","r",stdin); 40 scanf("%d",&x); 41 for(int tt=0;tt<x;tt++){ 42 if(tt!=0) 43 printf("\n"); 44 scanf("%d%d",&n,&t); 45 memset(tree,0,sizeof(tree)); 46 for(int i=0;i<t;i++){ 47 scanf("%s",s); 48 if(s[0]=='C'){ 49 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 50 add(x1,y1,1); 51 add(x2+1,y1,-1); 52 add(x1,y2+1,-1); 53 add(x2+1,y2+1,1); 54 } 55 else{ 56 scanf("%d%d",&x1,&y1); 57 int ans=gsum(x1,y1); 58 if(ans%2==1) 59 printf("1\n"); 60 else 61 printf("0\n"); 62 } 63 } 64 } 65 return 0; 66 }
二维线段树:
成段更新,单点查询;
View Code
1 #include<stdio.h> 2 #include<string.h> 3 #define size 1010 4 5 int sum[size<<2][size<<2]; 6 int n,q,ans; 7 8 void build_y(int l,int r,int rt,int t){ 9 sum[t][rt]=0; 10 if(l==r) 11 return ; 12 int mid=(l+r)>>1; 13 build_y(l,mid,rt<<1,t); 14 build_y(mid+1,r,rt<<1|1,t); 15 } 16 void build_x(int l,int r,int rt){ 17 build_y(1,n,1,rt); 18 if(l==r) 19 return ; 20 int mid=(l+r)>>1; 21 build_x(l,mid,rt<<1); 22 build_x(mid+1,r,rt<<1|1); 23 } 24 25 void update_y(int Ly,int Ry,int l,int r,int rt,int t){ 26 if(Ly<=l && Ry>=r){ 27 sum[t][rt]^=1; 28 return ; 29 } 30 int mid=(l+r)>>1; 31 if(Ly<=mid) update_y(Ly,Ry,l,mid,rt<<1,t); 32 if(Ry> mid) update_y(Ly,Ry,mid+1,r,rt<<1|1,t); 33 } 34 void update_x(int Lx,int Rx,int Ly,int Ry,int l,int r,int rt){ 35 if(Lx<=l && Rx>=r){ 36 update_y(Ly,Ry,1,n,1,rt); 37 return ; 38 } 39 int mid=(l+r)>>1; 40 if(Lx<=mid) update_x(Lx,Rx,Ly,Ry,l,mid,rt<<1); 41 if(Rx> mid) update_x(Lx,Rx,Ly,Ry,mid+1,r,rt<<1|1); 42 } 43 44 void query_y(int y,int l,int r,int rt,int t){ 45 ans^=sum[t][rt]; 46 if(l==r) 47 return; 48 int mid=(l+r)>>1; 49 if(y<=mid) query_y(y,l,mid,rt<<1,t); 50 else query_y(y,mid+1,r,rt<<1|1,t); 51 } 52 void query(int x,int y,int l,int r,int rt){ 53 query_y(y,1,n,1,rt); 54 if(l==r) 55 return ; 56 int mid=(l+r)>>1; 57 if(x<=mid) query(x,y,l,mid,rt<<1); 58 else query(x,y,mid+1,r,rt<<1|1); 59 } 60 int main() 61 { 62 int x,i; 63 int x1,y1,x2,y2; 64 char s[3]; 65 // freopen("test","r",stdin); 66 scanf("%d",&x); 67 for(int tt=0;tt<x;tt++){ 68 if(tt!=0) 69 printf("\n"); 70 scanf("%d%d",&n,&q); 71 build_x(1,n,1); 72 for(i=0;i<q;i++){ 73 scanf("%s",s); 74 if(s[0]=='C'){ 75 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 76 update_x(x1,x2,y1,y2,1,n,1); 77 } 78 else{ 79 scanf("%d%d",&x1,&y1); 80 ans=0; 81 query(x1,y1,1,n,1); 82 printf("%d\n",ans); 83 } 84 } 85 } 86 return 0; 87 }


浙公网安备 33010602011771号