poj2155

poj2155

题意

二维区间更新,单点查询。

分析

二维线段树。
也可以用二维树状数组去做,维护矩阵前缀和。

code

#include<cstdio>
using namespace std;
typedef long long ll;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
const int MAXN = 4001;
int n, val[MAXN][MAXN];
int x, y, xl, xr, yl, yr;
void subBuild(int xrt, int l, int r, int rt) {
    val[xrt][rt] = 0;
    if(l != r) {
        int m = l + r >> 1;
        subBuild(xrt, lson);
        subBuild(xrt, rson);
    }
}
void build(int l, int r, int rt) {
    subBuild(rt, 1, n, 1);
    if(l != r) {
        int m = l + r >> 1;
        build(lson);
        build(rson);
    }
}
void subUpdate(int xrt, int l, int r, int rt) {
    if(l >= yl && r <= yr) val[xrt][rt] ^= 1;
    else {
        int m = l + r >> 1;
        if(yl <= m) subUpdate(xrt, lson);
        if(yr > m) subUpdate(xrt, rson);
    }
}
void update(int l, int r, int rt) {
    if(l >= xl && r <= xr) subUpdate(rt, 1, n, 1);
    else {
        int m = l + r >> 1;
        if(xl <= m) update(lson);
        if(xr > m) update(rson);
    }
}
int ans;
void subQuery(int xrt, int l, int r, int rt) {
    ans ^= val[xrt][rt];
    if(l != r) {
        int m = l + r >> 1;
        if(y <= m) subQuery(xrt, lson);
        else subQuery(xrt, rson);
    }
}
void query(int l, int r, int rt) {
    subQuery(rt, 1, n, 1);
    if(l != r) {
        int m = l + r >> 1;
        if(x <= m) query(lson);
        else query(rson);
    }
}
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        int q;
        scanf("%d%d", &n, &q);
        build(1, n, 1);
        while(q--) {
            char s[2];
            scanf("%s", s);
            if(s[0] == 'C') {
                scanf("%d%d%d%d", &xl, &yl, &xr, &yr);
                update(1, n, 1);
            } else {
                scanf("%d%d", &x, &y);
                ans = 0;
                query(1, n, 1);
                printf("%d
", ans);
            }
        }
        if(T) puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ftae/p/7746238.html