POJ 2155 二维线段树
2016-01-18 18:53
411 查看
POJ 2155
题目链接:
http://www.bnuoj.com/v3/problem_show.php?pid=2274
题意:
给一个01矩阵,每次可以进行操作将[x1,x2,y1,y2]内的所有元素0变1、1变0。也可以进行询问,询问某一个格子的0和1。
输出询问。
思路:
二维线段树版题,稍微转化一下记录查询一个点时它所经过的路径上经过偶数次修改就为0,奇数次为1。
线段树有两种写法,第一种把下标放在树的结点中,时不时会MLE。第二种是放在询问的函数里。这时候似乎开一个宏定义能够省很多写法,定义一个左儿子和右儿子。
二维的线段树有点类似二维树状数组,无非是两边更新下,多写一步啦。
开struct会MLE,写太残过段时间补一个好一点的版。
源码:
题目链接:
http://www.bnuoj.com/v3/problem_show.php?pid=2274
题意:
给一个01矩阵,每次可以进行操作将[x1,x2,y1,y2]内的所有元素0变1、1变0。也可以进行询问,询问某一个格子的0和1。
输出询问。
思路:
二维线段树版题,稍微转化一下记录查询一个点时它所经过的路径上经过偶数次修改就为0,奇数次为1。
线段树有两种写法,第一种把下标放在树的结点中,时不时会MLE。第二种是放在询问的函数里。这时候似乎开一个宏定义能够省很多写法,定义一个左儿子和右儿子。
二维的线段树有点类似二维树状数组,无非是两边更新下,多写一步啦。
开struct会MLE,写太残过段时间补一个好一点的版。
源码:
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <vector> using namespace std; const int MAXN = 1000 + 5; //struct Tree //{ // int lx; int rx; // int ly; int ry; // bool val; // Tree(){} // Tree(int _lx, int _rx, int _ly, int _ry, int _val){ // lx = _lx, ly = _ly, rx = _rx, ry = _ry; // val = _val; // } //}tree[MAXN * 4][MAXN * 4]; int tree[MAXN * 4][MAXN * 4]; int n, q; char str[10]; //void buildy(int ox, int lx, int rx, int oy, int ly, int ry) //{ // tree[ox][oy] = Tree(lx, rx, ly, ry, 0); // if(ly == ry) return; // int midy = (ly + ry) >> 1; // buildy(ox, lx, rx, oy << 1, ly, midy); // buildy(ox, lx, rx, (oy << 1) + 1, midy + 1, ry); //} //void buildx(int ox, int lx, int rx, int oy, int ly, int ry) //{ // buildy(ox, lx, rx, oy, ly, ry); // if(lx == rx) return; // int midx = (lx + rx) >> 1; // buildy((ox << 1), lx, midx, oy, ly, ry); // buildy((ox << 1) + 1, midx + 1, rx, oy, ly, ry); //} void updatey(int ox, int oy, int y1, int y2, int ly, int ry) { // printf("in updateY ox = %d, lx = %d, rx = %d, ly = %d, ry = %d\n", ox, tree[ox][oy].lx, tree[ox][oy].rx, tree[ox][oy].ly, tree[ox][oy].ry); // printf("y1 = %d, y2 = %d\n", y1, y2); if(ly >= y1 && ry <= y2){ tree[ox][oy] = !tree[ox][oy]; return; } int mid = (ly + ry) >> 1; if(mid >= y1) updatey(ox, (oy << 1), y1, y2, ly, mid); if(mid < y2) updatey(ox, (oy << 1) +1 , y1, y2, mid + 1, ry); } void updatex(int ox, int x1, int x2, int oy, int y1, int y2, int lx, int rx, int ly, int ry) { // printf("in updatex ox = %d, lx = %d, rx = %d, ly = %d, ry = %d\n", ox, tree[ox][oy].lx, tree[ox][oy].rx, tree[ox][oy].ly, tree[ox][oy].ry); // printf("x1 = %d, x2 = %d, y1= %d, y2 = %d\n", x1, x2, y1, y2); if(lx >= x1 && rx <= x2){ // printf("first\n"); updatey(ox, oy, y1, y2, ly, ry); return; } int mid = (lx + rx) >> 1; if(x1 <= mid) updatex(ox << 1, x1, x2, oy, y1, y2, lx, mid, ly, ry); if(x2 > mid) updatex((ox << 1) + 1, x1, x2, oy, y1, y2, mid + 1, rx, ly, ry); } int queryy(int ox, int x, int oy, int y, int lx, int rx, int ly, int ry) { // system("pause"); // if(ox == 3){ // printf("ox = %d, oy = %d, val = %d\n", ox, oy, tree[ox][oy].val); // // for(int i = 1 ; i <= 3 ; i++){ // for(int j = 1 ; j <= 3 ; j++) // printf("%d ", tree[i][j].val); // printf("\n"); // } // } if(ly == ry) return tree[ox][oy]; int ans = tree[ox][oy]; int mid = (ly + ry) >> 1; if(y <= mid) ans += queryy(ox, x, oy << 1, y, lx, rx, ly, mid); else ans += queryy(ox, x, (oy << 1) + 1, y, lx, rx, mid + 1, ry); // printf("in queryY ox = %d, x = %d, oy = %d, y = %d, ans = %d\n", ox, x, oy, y, ans); return ans; } int queryx(int ox, int x, int oy, int y, int lx, int rx, int ly, int ry) { int ans = queryy(ox, x, oy, y, lx, rx, ly, ry); if(lx == rx) return ans; int mid = (lx + rx) >> 1; if(x <= mid) ans += queryx((ox << 1), x, oy, y, lx, mid, ly, ry); else ans += queryx((ox << 1) + 1, x, oy, y, mid + 1, rx, ly, ry); // printf("in queryx ox = %d, x = %d, oy = %d, y = %d, ans = %d\n", ox, x, oy, y, ans); // system("pause"); return ans; } int main() { int T; scanf("%d", &T); int f = 1; while(T--){ if(f) f = 0; else printf("\n"); scanf("%d%d", &n, &q); memset(tree, 0, sizeof(tree)); // buildx(1, 1, n, 1, 1, n); for(int i = 0 ; i < q ; i++){ int x1, y1, x2, y2; scanf("%s%d%d", str, &x1, &y1); if(str[0] == 'C'){ scanf("%d%d", &x2, &y2); updatex(1, x1, x2, 1, y1, y2, 1, n, 1, n); } else{ int ans = queryx(1, x1, 1, y1, 1, n, 1, n); printf("%d\n", ans % 2); } // for(int i = 1 ; i <= 3 ; i++){ // for(int j = 1 ; j <= 3 ; j++) // printf("%d ", tree[i][j].val); // printf("\n"); // } } } return 0; }
相关文章推荐
- 我的算法学习之路
- 算法导论第三版习题4.4
- s5pv210编译qt
- 获取文章的字数或则字符数
- 反编译[学习笔记]
- DEDE如何文章页调用相关文章列表
- cocos2d-x中ScrollView内的元素位置问题
- 通过Windows Media Player控件获取音频文件的时长
- 织梦安装时dede不能写入 怎么设置啊
- 孩子冷不冷?一指辨寒热!
- 操作符
- FSM(状态机)、HFSM(分层状态机)、BT(行为树)的区别
- 企业库判断数据库连接类型
- dede后台怎么进入 DEDE如何进入系统管理后台
- dede列表页调用文章点击次数
- Android奇葩记录
- leetcode--search in rotated sorted arry
- dede如何添加搜索功能, 让网站支持搜索
- 基于单链表的操作
- 织梦后台提示密码错误