1. 程式人生 > >CF-339D-線段樹

CF-339D-線段樹

http://codeforces.com/problemset/problem/339/D

  給出一個序列。每次更改其中一個值然後詢問序列的f(),序列的f()定義為: 每相鄰兩個元素按位或得到長度減半的序列,在對每相鄰兩個元素按位異或得到長度再次減半的序列。。。。更替的進行按位或/異或,

直至序列長度為1,輸出這個數即可。

  op維護當前節點的操作符號,g維護當前區間價值。

  

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define ULL unsigned long long
 5
const int maxn=150000; 6 int a[maxn]; 7 class sg_tree 8 { 9 public: 10 #define mid ((L+R)>>1) 11 #define lc (id<<1) 12 #define rc (id<<1|1) 13 14 int N,g[maxn<<2]; 15 bool op[maxn<<2]; 16 17 void build(int id,int L,int R) 18 { 19 if
(L==R) 20 { 21 scanf("%d",&g[id]); 22 op[id]=1; 23 return; 24 } 25 build(lc,L,mid); 26 build(rc,mid+1,R); 27 op[id]=(op[lc]^1); 28 if(op[id]==0) g[id]=(g[lc]|g[rc]); 29 else g[id]=(g[lc]^g[rc]);
30 } 31 32 void change(int id,int L,int R,int p,int b) 33 { 34 if(L==R) 35 { 36 g[id]=b; 37 return; 38 } 39 if(p<=mid)change(lc,L,mid,p,b); 40 else change(rc,mid+1,R,p,b); 41 if(op[id]==0) g[id]=(g[lc]|g[rc]); 42 else g[id]=(g[lc]^g[rc]); 43 } 44 } ac; 45 int main() 46 { 47 int n,m,p,b; 48 scanf("%d%d",&n,&m); 49 ac.N=(1<<n); 50 ac.build(1,1,ac.N); 51 while(m--) 52 { 53 scanf("%d%d",&p,&b); 54 ac.change(1,1,ac.N,p,b); 55 printf("%d\n",ac.g[1]); 56 } 57 return 0; 58 } 59 /* 60 2 4 61 1 6 3 5 62 1 4 63 3 4 64 1 2 65 1 2 66 67 */