此题的时间复杂度要求的有点高,所以普通的方法肯定超时.
由于时类似于单点更新的所以可以用线段树,主要就是解决层数的用|还是^的问题.所以单设一个数组来记录当前的
层数问题.
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <queue> #include <cmath> #define inf 0x3f3f3f3f; #define ls l,mid,rt<<1 #define rs mid+1,r,rt<<1|1 #define maxn 5000000 int arr[maxn],tmp[maxn]; using namespace std; int Up(int rt,int ans) { if(ans==0) return 0; if(ans&1) arr[rt]=arr[rt<<1]|arr[rt<<1|1]; else arr[rt]=arr[rt<<1]^arr[rt<<1|1]; } void bu(int l,int r,int rt,int ans) { if(l==r) { scanf("%d",&arr[rt]);return ; } int mid=(l+r)>>1; bu(ls,ans-1); bu(rs,ans-1); tmp[rt]=ans; Up(rt,tmp[rt]); } void Q(int l,int r,int rt,int id,int a) { if(l==r) { arr[rt]=a;return ; } int mid=(l+r)>>1; if(id<=mid) Q(ls,id,a); else Q(rs,id,a); Up(rt,tmp[rt]); } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { int k=(int)pow(2,n); bu(1,k,1,n); int id,a; for(int i=0;i<m;i++) { scanf("%d%d",&id,&a); Q(1,k,1,id,a); cout<<arr[1]<<endl; } } return 0; }