POJ - 2155 Matrix (二维树状数组 + 区间修改 + 单点求值 或者 二维线段树 + 区间更新 + 单点求值)
2015-08-07 20:16
513 查看
POJ - 2155Matrix
1 2 10 C 2 1 2 2 Q 2 2 C 2 1 2 1 Q 1 1 C 1 1 2 1 C 1 2 1 2 C 1 1 2 2 Q 1 1 C 1 1 2 1 Q 2 1Sample Output 1 0 0 1 题目意思是给你一个矩阵,最开始都是为0,然后给你一个左上角的坐标,右下角的坐标,将这个区域的0 -> 1,1 -> 0,然后给你一个点让你求出他此时的结果是1还是0. 这里可以用树状数组的区间修改以及单点求值,只是这里是二维的树状数组,原理是一样的。 将其改变的话,可以如此,假设最开始[1....x2][1....y2]为偶数的话(这里就是看成是前辍和) 先将[1....x2][1....y2]增加1,变为奇数,然后将[1...x1 - 1][y2]增加1变为偶数,将[1....x2][y1]增加1变为偶数,而他们中间重叠的[1....x1 - 1][1....x2 - 1]部分则是被改变了三次,还是奇数,所以还有加1,将他变为偶数,如此除了[x1....x2][y1....y2]变了外,其他的地方依旧没有改变。 /* Author: 2486 Memory: 4304 KB Time: 547 MS Language: G++ Result: Accepted */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 1000 + 5; int C[MAXN][MAXN]; int N, X, M, x, y, x1, x2, y1, y2; char op[10]; int lowbits(int x){ return x & (-x); } void add(int x,int y){ for(int i = x; i <= N;i += lowbits(i)){ for(int j = y;j <= N;j += lowbits(j)){ C[i][j] ++; } } } int query(int x,int y){ int ret = 0; for(int i = x;i > 0;i -= lowbits(i)){ for(int j = y;j > 0;j -= lowbits(j)){ ret += C[i][j]; } } return ret; } int main(){ //freopen("D://imput.txt","r",stdin); scanf("%d", &X); while(X --){ memset(C, 0, sizeof(C)); scanf("%d%d", &N, &M); while(M --){ scanf("%s", op); if(op[0] == 'C'){ scanf("%d%d%d%d", &x1, &y1, &x2, &y2); x2 ++; y2 ++; add(x1, y1); add(x1, y2); add(x2, y1); add(x2, y2); } else{ scanf("%d%d", &x, &y); printf("%d\n", query(x,y) & 1);//求和即代表求点 } } if(X)printf("\n"); } return 0; }[/code] 线段树代码: /*Author: 2486Memory: 63688 KB Time: 1579 MSLanguage: G++ Result: Accepted*/#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;#define lson rt << 1, l, mid#define rson rt << 1|1, mid + 1, r#define root 1, 1, Nconst int MAXN = 1000 + 5;int N, T, CASE, x1, y1, x2, y2, ret, x, y;char op[5];int sum[MAXN << 2][MAXN << 2];void update_r(int cr, int y1, int y2, int rt, int l, int r) {if(y1 <= l && r <= y2) {sum[cr][rt] = !sum[cr][rt];return ;}int mid = (l + r) >> 1;if(y1 <= mid) update_r(cr, y1, y2, lson);if(y2 > mid) update_r(cr, y1, y2, rson);}void update_c(int x1, int y1, int x2, int y2, int rt, int l, int r) {if(x1 <= l && r <= x2) {update_r(rt, y1, y2, root);return;}int mid = (l + r) >> 1;if(x1 <= mid) update_c(x1, y1, x2, y2, lson);if(x2 > mid) update_c(x1, y1, x2, y2, rson);}void query_r(int cr, int y1, int y2, int rt, int l, int r) {if(sum[cr][rt]) ret ++;if(y1 <= l && r <= y2) {return ;}int mid = (l + r) >> 1;if(y1 <= mid) query_r(cr, y1, y2, lson);if(y2 > mid) query_r(cr, y1, y2, rson);}void query_c(int x1, int y1, int x2, int y2, int rt, int l, int r) {query_r(rt, y1, y2, root);//选择覆盖了子树的个数if(x1 <= l && r <= x2) {return;}int mid = (l + r) >> 1;if(x1 <= mid) query_c(x1, y1, x2, y2, lson);if(x2 > mid) query_c(x1, y1, x2, y2, rson);}int main() {//freopen("D://imput.txt","r",stdin);scanf("%d", &CASE);while(CASE --) {memset(sum, 0, sizeof(sum));scanf("%d%d", &N, &T);while(T --) {scanf("%s", op);if(op[0] == 'C') {scanf("%d%d%d%d", &x1, &y1, &x2, &y2);update_c(x1, y1, x2, y2, root);} else {scanf("%d%d", &x, &y);ret = 0;query_c(x, y, x, y, root);printf("%d\n", ret & 1);}}if(CASE)printf("\n");}return 0;}[/code] |
相关文章推荐
- hdu4198
- FFmpeg Windows 开发环境简单搭建 教程
- 线程的三种创建方法
- 验证邮箱是否存在原理
- java Math.floor,Math.ceil,Math.rint,Math.round用法详解
- uvalive 3616
- 浅谈对主成分分析(PCA)算法的理解
- C#高级编程----反射的小结
- UVa-12166 Equilibrium Mobile
- Nginx负载均衡配置实例详解
- (素材源码)swanzhu学IOS(三)打飞机
- 在visual studio 2010中调用ffmpeg
- 伊斯坦布尔之旅第一站:韩国仁川机场免费中转旅游
- Linux 下面安装redis
- Android之SDK如何更新
- NSURLConnection使用
- 微软源代码管理工具TFS2013安装与使用详细图文教程(Vs2013)
- HDU2303(数论)大整数求余+素数筛选
- 阿里云服务器ubuntu安装java运行环境
- 蓝牙的RSSI转换为信号强度百分百