Matrix
POJ - 2155
题意:
给出矩阵左上角和右下角坐标,矩阵里的元素 1变0 ,0 变1,然后给出询问,问某个点是多少
先考虑一维: 例如区间x,y要加上v, 扫描线思路让x处加v,让y+1处减v,结合树状数组,则x处的值就为【1,x】的和了。
下面这段来自大佬博客~
/*
每次修改的时候,给定一个格子修改的范围(x,y),这样我们不妨把这个范围变成两个点,一个为更改的初始节点x,另一个为更改的终止节点y+1,然后往这列格子中的这两个节点中加1。
每次询问x的时候只需计算出 Sumx = ∑di 这样就可以求出第 x个
i=1
格子被修改过几次,输出的答案就是Sumx mod 2。
*/
考虑二维:经典二维树状数组操作, 运用容斥原理
即 add(x,y,1);
add(x,y1+1,-1);
add(x1+1,y,-1);
add(x1+1,y1+1,1);
可解
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
const int N = 1050;
int bit[N][N];
int n;
using namespace std;
void add(int x, int y, int z){
for(int i = x; i <= n; i += i&(-i)){
for(int j = y; j <= n; j += j&(-j)){
bit[i][j] += z;
}
}
}
int sum(int x, int y){
int res = 0;
for(int i = x; i; i -= i&(-i)){
for(int j = y; j; j -= j&(-j)){
res += bit[i][j];
}
}
return res;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(0);
int t;
cin >> t;
while(t--){
int q;
cin >> n >> q;
memset(bit, 0, sizeof(bit));
for(int i = 0; i < q; i++){
char op;
cin >> op;
int x1, y1, x2, y2;
if(op == 'C'){
cin >> x1 >> y1 >> x2 >> y2;
add(x1, y1, 1);
add(x1, y2+1, -1);
add(x2+1, y1, -1);
add(x2+1, y2+1, 1);
} else{
cin >> x1 >> y1;
cout << sum(x1, y1)%2 << '\n';
}
}
if(t) cout << '\n';
}
return 0;
}
本文详细介绍了如何使用二维树状数组解决矩阵元素翻转问题,通过容斥原理优化查询效率。文章首先从一维树状数组引入,再逐步过渡到二维情况,并提供了完整的代码实现。
1844

被折叠的 条评论
为什么被折叠?



