您的位置:首页 > 其它

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,写太残过段时间补一个好一点的版。

源码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: