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 */

 

posted @ 2018-11-02 18:09  *zzq  阅读(251)  评论(0编辑  收藏  举报