题意:
给定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 <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
template <class T>
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 <class T>
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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-09 05:23:44