poj-2155 matrix :二维树状数组
作者:互联网
前情提要:原题是英文题面,我直接在某谷上找翻译,由于过于信任某谷 ,拿着错误题面干瞪眼好久…
题面:
- 有一个矩阵,里面所有数字都是0,有两种操作
- c操作,把一个矩形里的数字都取非
- q操作,展示某个点的值。
思路:
- 取非/异或等操作都有一个特性–只有奇数次操作才有用
- 所以只需存有几次操作就行
- 用树状数组存次数
- 最后只要注意统计答案时的query就行(容斥原理)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#define ll long long
#define il inline
#define re register
//有一个矩阵,里面所有数字都是0,有两种操作
//c操作,把一个矩形里的数字都取非
//q操作,展示某个点的值。
using namespace std;
int T;
int n, q;
int c[1010][1010];
il int lowbit(int x) {
return x & (-x);
}
il void update(int x, int y, int v) {
//二维更新
for(int i = x; i <= n; i += lowbit(i)) {
for(int j = y; j <= n; j += lowbit(j)) {
c[i][j] += v;//这个区间的点取非次数++
}
}
}
il int getsum(int x, int y) {
int res = 0;
for(int i = x; i > 0; i-= lowbit(i)) {
for(int j = y; j > 0; j -= lowbit(j)) {
res += c[i][j];
}
}
return res;//整个矩形的点的取非次数
}
int main() {
scanf("%d", &T);
while(T--) {
memset(c, 0, sizeof(c));
char ch[3];
scanf("%d%d", &n, &q);
while(q--) {
scanf("%s", &ch);
if(ch[0] == 'C') {
int x1, x2, y1, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
//更新嘛
update(x1, y1, 1);
update(x2+1, y2+1, 1);
update(x1, y2+1, -1);//右上
update(x2+1, y1, -1);//左下
}else {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", getsum(x, y)%2);//偶数次就当不存在
}
}
printf("\n");
}
return 0;
}
标签:matrix,int,scanf,d%,update,2155,poj,操作,include 来源: https://blog.csdn.net/weixin_42754202/article/details/95351166