codeforces 339D Xenia and Bit Operations 线段树

题目链接
题意:
给定n,下面2^n个数。
第一次 把 a1|a2, a3|a4, 如此得到一个 2^(n-1)个数的序列。
再把这个序列 a1^a2, a3^a4 , 得到一个2^(n-2) 个数的序列
再进行 a1|a2, a3|a4 ···
直到只剩下一个数v, 我们称v是这个2^n 序列的权值。

下面m个询问:
询问格式: p, b 表示 a[p] = b; 再输出此时序列的权值。
思路:因为这个序列一定是2的倍数,所以用线段树直接这样操作即可。push_up时的深度奇偶来判断此时应该用 | 还是 ^。

#include 
#include 
#include 
#include 
template 
inline bool rd(T &ret) {
    char c; int sgn;
    if (c = getchar(), c == EOF) return 0;
    while (c != '-' && (c<'0' || c>'9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}
template 
inline void pt(T x) {
    if (x <0) {
        putchar('-');
        x = -x;
    }
    if (x>9) pt(x / 10);
    putchar(x % 10 + '0');
}
using namespace std;
typedef long long ll;
const int N = (1<<17)+10;
#define lson (id<<1)
#define rson (id<<1|1)
#define L(id) tree[id].l
#define R(id) tree[id].r
#define V(id) tree[id].v
struct Node {
    int l, r, v;
}tree[N << 2];
int n, q, a[N];
void up(int id,int _or) {
    if(_or) V(id) = V(lson) | V(rson);
    else V(id) = V(lson) ^ V(rson);
}
void build(int l, int r, int id, int dep) {
    L(id) = l; R(id) = r;
    if (l == r) {
        V(id) = a[l];return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, lson, dep^1);
    build(mid + 1, r, rson, dep^1);
    up(id, dep);
}
void change(int p, int v, int id, int dep) {
    if (L(id) == R(id)) {
        V(id) = v;
        return;
    }
    int mid = (L(id) + R(id)) >> 1;
    if (p <= mid)change(p, v, lson, dep^1);
    else change(p, v, rson, dep^1);
    up(id, dep);
}
int main() {
    rd(n); rd(q);
    n = 1 << n;
    for (int i = 1; i <= n; i++)rd(a[i]);
    build(1, n, 1, n & 1);
    while (q--) {
        int p, b;
        rd(p); rd(b);
        change(p, b, 1, n & 1);
        pt(V(1));puts("");
    }
    return 0;
}

你可能感兴趣的:(水题,线段树,codeforce)