二维树状数组
1 #include<iostream> 2 #include<math.h> 3 #include<algorithm> 4 #include<stdlib.h> 5 using namespace std; 6 #define ll long long 7 #define re(i,n) for(int i=0;i<n;i++) 8 const int maxn = 1007; 9 int c[maxn][maxn]; 10 int n, q; 11 int lowbit(int x){ 12 return x&(-x); 13 } 14 void update(int x, int y){ 15 for (int i = x; i >0; i-=lowbit(i)) 16 for (int j = y; j >0; j -= lowbit(j)) 17 c[i][j] ^= 1; 18 } 19 int query(int x, int y){ 20 int ans = 0; 21 for (int i = x; i <= n; i+=lowbit(i)) 22 for (int j = y; j <= n; j += lowbit(j)){ 23 ans ^= c[i][j]; 24 } 25 return ans; 26 } 27 int main(){ 28 //freopen("in.txt", "r", stdin); 29 int T; cin >> T; 30 while (T--){ 31 scanf("%d%d", &n, &q); 32 memset(c, 0, sizeof(c)); 33 while (q--){ 34 char op[2]; scanf("%s", op); 35 if (op[0] == ‘Q‘){ 36 int x, y; scanf("%d%d", &x, &y); 37 printf("%d\n", query(x, y)); 38 } 39 else{ 40 int fx, fy, tx, ty; scanf("%d%d%d%d", &fx, &fy, &tx, &ty); 41 if (fx > tx)swap(fx, tx); if (fy > ty)swap(fy, ty); 42 fx--, fy--; 43 update(fx, fy); 44 update(tx, ty); 45 update(fx, ty); 46 update(tx, fy); 47 } 48 } 49 puts(""); 50 } 51 return 0; 52 }
二维线段树
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 using namespace std; 5 #define ll long long 6 #define re(i,n) for(int i=0;i<n;i++) 7 #define ls(x) x<<1,f,mid 8 #define rs(x) x<<1|1,mid+1,t 9 const int maxn = 1005; 10 int n, q; 11 int fx, fy, tx, ty, x, y; 12 int ans; 13 bool a[maxn << 2][maxn << 2]; 14 void updatey(int i, int j, int f, int t){ 15 if (fy <= f&&ty >= t){ 16 a[i][j] ^= 1; 17 return; 18 } 19 int mid = (f + t) >> 1; 20 if (fy <= mid)updatey(i,ls(j)); 21 if (ty > mid)updatey(i, rs(j)); 22 } 23 void updatex(int i, int f, int t){ 24 if (fx<=f&&tx>=t){ 25 updatey(i, 1, 1, n); 26 return; 27 } 28 int mid = (f + t) >> 1; 29 if (fx <= mid)updatex(ls(i)); 30 if (tx > mid)updatex(rs(i)); 31 } 32 void queryy(int i, int j, int f, int t){ 33 ans += a[i][j]; 34 if (f == t)return; 35 int mid = (f + t) >> 1; 36 if (y > mid)queryy(i,rs(j)); 37 else queryy(i, ls(j)); 38 } 39 void queryx(int i, int f, int t){ 40 queryy(i, 1, 1, n); 41 if (f == t)return; 42 int mid = (f + t) >> 1; 43 if (x > mid)queryx(rs(i)); 44 else queryx(ls(i)); 45 } 46 int main(){ 47 //freopen("in.txt", "r", stdin); 48 int T; cin >> T; 49 while (T--){ 50 scanf("%d%d", &n, &q); 51 memset(a, 0, sizeof(a)); 52 /*应该用memset,用for循环一定要注意初始化的不是n,而是全部. 53 公元2015年9.20日在于此坑. 54 re(i, n + 1)re(j, n + 1)a[i][j] = 0; 55 */ 56 while (q--){ 57 char op[2]; scanf("%s", op); 58 if (op[0] == ‘Q‘){ 59 scanf("%d%d",&x,&y); 60 ans = 0; 61 queryx(1, 1, n); 62 printf("%d\n", ans & 1); 63 } 64 else{ 65 scanf("%d%d%d%d", &fx, &fy, &tx, &ty); 66 if (fx > tx)swap(fx, tx); if (fy > ty)swap(fy, ty); 67 updatex(1,1,n); 68 //debug(); 69 } 70 } 71 if (T)puts(""); 72 } 73 return 0; 74 }
zkw二维线段树 开区间写法
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn =1007; 6 typedef long long ll; 7 #define re(i,n) for(int i=0;i<n;i++) 8 bool tr[maxn << 2][maxn << 2]; 9 int n, q,sz; 10 bool yquery(int x, int y){ 11 y += sz; 12 bool ans = 0; 13 /* 14 因为1是哨兵节点,1必然始终都为0,不曾变化,所以算上1也无妨 15 */ 16 while (y){ 17 ans ^= tr[x][y]; 18 y >>= 1; 19 } 20 return ans; 21 } 22 bool query(int x,int y){ 23 x += sz; 24 int ans = 0; 25 while (x){ 26 ans ^= yquery(x, y); 27 x >>= 1; 28 } 29 return ans; 30 } 31 void yupdate(int x, int fy, int ty){ 32 fy += sz - 1, ty += sz + 1; 33 while (fy^ty ^ 1){ 34 if (~fy & 1)tr[x][fy ^ 1] ^= 1; 35 if (ty & 1)tr[x][ty ^ 1] ^= 1; 36 fy >>= 1, ty >>= 1; 37 } 38 } 39 void update(int fx,int fy,int tx,int ty){ 40 fx += sz - 1, tx += sz + 1; 41 while (fx^tx ^ 1){ 42 if (~fx & 1)yupdate(fx^1, fy, ty); 43 if (tx & 1)yupdate(tx ^ 1, fy, ty); 44 fx >>= 1, tx >>= 1; 45 } 46 } 47 int main(){ 48 //freopen("in.txt", "r", stdin); 49 int T; cin >> T; 50 while (T--){ 51 scanf("%d%d", &n, &q); 52 sz = 1; while (sz < n+2)sz <<= 1; 53 memset(tr, 0, sizeof(tr)); 54 while (q--){ 55 char op[2]; scanf("%s", op); 56 if (op[0] == ‘Q‘){ 57 int x, y; scanf("%d%d", &x, &y); 58 bool ans = query(x, y); 59 printf("%d\n", ans); 60 } 61 else{ 62 int fx, fy, tx, ty; scanf("%d%d%d%d", &fx, &fy, &tx, &ty); 63 if (fx > tx)swap(fx, tx); if (fy > ty)swap(fy, ty); 64 update(fx, fy, tx, ty); 65 } 66 } 67 puts(""); 68 } 69 return 0; 70 }
zwk二维线段树闭区间写法
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 using namespace std; 5 const int maxn =1007; 6 typedef long long ll; 7 #define re(i,n) for(int i=0;i<n;i++) 8 bool tr[maxn << 2][maxn << 2]; 9 int n, q,sz; 10 bool yquery(int x, int y){ 11 y += sz-1; 12 bool ans = 0; 13 /* 14 因为1是哨兵节点,1必然始终都为0,不曾变化,所以算上1也无妨 15 */ 16 while (y){ 17 ans ^= tr[x][y]; 18 y >>= 1; 19 } 20 return ans; 21 } 22 bool query(int x,int y){ 23 x += sz-1; 24 int ans = 0; 25 while (x){ 26 ans ^= yquery(x, y); 27 x >>= 1; 28 } 29 return ans; 30 } 31 /* 32 开区间=闭区间-两个端点. 33 所以,先处理两个端点之后就变成了开区间. 34 两个端点处理时要加上一个判断,l==r,如果相等,那就不能对同一个点处理两次,只处理一个点然后返回就行了;如果不等,那就先处理两端,再按照开区间的方式进行处理. 35 */ 36 void yupdate(int x, int fy, int ty){ 37 fy += sz - 1, ty += sz -1; 38 if (fy == ty){ tr[x][fy] ^= 1; return; } 39 tr[x][fy] ^= 1, tr[x][ty] ^= 1; 40 while (fy^ty ^ 1){ 41 if (~fy & 1)tr[x][fy ^ 1] ^= 1; 42 if (ty & 1)tr[x][ty ^ 1] ^= 1; 43 fy >>= 1, ty >>= 1; 44 } 45 } 46 void update(int fx,int fy,int tx,int ty){ 47 fx += sz - 1, tx += sz - 1; 48 if (fx == tx){ 49 yupdate(fx, fy, ty); return; 50 } 51 yupdate(fx, fy, ty), yupdate(tx, fy, ty); 52 while (fx^tx ^ 1){ 53 if (~fx & 1)yupdate(fx^1, fy, ty); 54 if (tx & 1)yupdate(tx ^ 1, fy, ty); 55 fx >>= 1, tx >>= 1; 56 } 57 } 58 int main(){ 59 freopen("in.txt", "r", stdin); 60 int T; cin >> T; 61 while (T--){ 62 scanf("%d%d", &n, &q); 63 sz = 1; while (sz < n)sz <<= 1; 64 memset(tr, 0, sizeof(tr)); 65 while (q--){ 66 char op[2]; scanf("%s", op); 67 if (op[0] == ‘Q‘){ 68 int x, y; scanf("%d%d", &x, &y); 69 bool ans = query(x, y); 70 printf("%d\n", ans); 71 } 72 else{ 73 int fx, fy, tx, ty; scanf("%d%d%d%d", &fx, &fy, &tx, &ty); 74 if (fx > tx)swap(fx, tx); if (fy > ty)swap(fy, ty); 75 update(fx, fy, tx, ty); 76 } 77 } 78 putchar(10);//换行是10,回车13,空格32 79 } 80 return 0; 81 }
时间: 2024-10-07 21:21:51