题目大意:
给定一个序列,每次选择一个点修改权值,然后求出全序列的值。
不难想到,直接用线段树维护就好了:
就一个单点修改
同时,在建树的时候,我们求出每一段的深度。pushup时,根据单双数来判断是按位或还是亦或运算。
code:
#include<bits/stdc++.h> using namespace std; #define N 1000010 #define QAQ 0 inline int read(){ int x = 0, s = 1; char c = getchar(); while(!isdigit(c)){ if(c == '-')s = -1; c = getchar(); } while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); } return x * s; } int a[N]; struct tree{ int w, deth; } t[N]; inline void pushup(int o){ /*更新*/ if(t[o].deth % 2) t[o].w = t[o << 1].w | t[o << 1 | 1].w; else t[o].w = t[o << 1].w ^ t[o << 1 | 1].w; return ; } void build(int o, int l, int r){ if(l == r){ t[o].w = a[r]; return ; } int mid = l + r >> 1; build(o << 1, l, mid); build(o << 1 | 1, mid + 1, r); t[o].deth = t[o << 1].deth + 1; /*记录深度*/ pushup(o); return ; } void update(int o, int l, int r, int x, int k){ /*经典操作: 单点修改*/ if(l > x || r < x) return ; if(l == x && r == x){ t[o].w = k; return ; } int mid = l + r >> 1; update(o << 1, l, mid, x, k); update(o << 1 | 1, mid + 1, r, x, k); pushup(o); return ; } int main(){ int n = read(), m = read(); for(int i = 1;i <= (1 << n); i++){ a[i] = read(); } build(1, 1, 1 << n); /*千万不要忘了先建树啊!! QAQ*/ while(m--){ int x = read(), y = read(); update(1, 1, 1 << n, x, y); printf("%d ", t[1].w); } return QAQ; }