Description
题目大意:
给你
2n
个数,更新其中的某个值,交替对这些数进行“或操作”和“异或操作”,每次得到最终的结果。
Solution
线段树模拟就好了,每次单点修改,每层节点用bool变量记录下是该进行“或操作”还是“异或操作”。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
template<typename T>inline void read(T &x){
T f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(x=0;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
x*=f;
}
const int maxn=132010;
struct Segment_Tree{
#define lc x<<1
#define rc x<<1|1
int L[maxn<<2],R[maxn<<2],sum[maxn<<2];
bool f[maxn<<2];
bool Build(int x,int *a,int l,int r){
L[x]=l;R[x]=r;
if(l==r)return sum[x]=a[l],f[x]=true;
int mid=(l+r)>>1;
if(Build(lc,a,l,mid),Build(rc,a,mid+1,r))
return sum[x]=sum[lc]|sum[rc],f[x]=false;
else return sum[x]=sum[lc]^sum[rc],f[x]=true;
}
void Change(int x,int pos,int val){
if(L[x]==R[x])return sum[x]=val,void();
int mid=(L[x]+R[x])>>1;
if(pos<=mid)Change(lc,pos,val);
else Change(rc,pos,val);
if(!f[x])sum[x]=sum[lc]|sum[rc];
else sum[x]=sum[lc]^sum[rc];
}
}tree;
int n,m,a[maxn];
int main(){
read(n);read(m);n=1<<n;
for(int i=1;i<=n;i++)read(a[i]);
tree.Build(1,a,1,n);
while(m--){
int pos,x;
read(pos);read(x);
tree.Change(1,pos,x);
printf("%d\n",tree.sum[1]);
}
return 0;
}