[线段树]Codeforces 339D Xenia and Bit Operations

Posted railgun000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[线段树]Codeforces 339D Xenia and Bit Operations相关的知识,希望对你有一定的参考价值。

Xenia and Bit Operations
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Xenia the beginner programmer has a sequence a, consisting of 2n non-negative integers: a1, a2, ..., a2n. Xenia is currently studying bit operations. To better understand how they work, Xenia decided to calculate some value v for a.

Namely, it takes several iterations to calculate value v. At the first iteration, Xenia writes a new sequence aor a2, aor a4, ..., a2n - 1 or a2n, consisting of 2n - 1 elements. In other words, she writes down the bit-wise OR of adjacent elements of sequence a. At the second iteration, Xenia writes the bitwise exclusive OR of adjacent elements of the sequence obtained after the first iteration. At the third iteration Xenia writes the bitwise OR of the adjacent elements of the sequence obtained after the second iteration. And so on; the operations of bitwise exclusive OR and bitwise OR alternate. In the end, she obtains a sequence consisting of one element, and that element is v.

Let‘s consider an example. Suppose that sequence a = (1, 2, 3, 4). Then let‘s write down all the transformations (1, 2, 3, 4)  →  (1 or 2 = 3, 3 or 4 = 7)  →  (3 xor 7 = 4). The result is v = 4.

You are given Xenia‘s initial sequence. But to calculate value v for a given sequence would be too easy, so you are given additional m queries. Each query is a pair of integers p, b. Query p, b means that you need to perform the assignment ap = b. After each query, you need to print the new value v for the new sequence a.

Input

The first line contains two integers n and m (1 ≤ n ≤ 17, 1 ≤ m ≤ 105). The next line contains 2n integers a1, a2, ..., a2n (0 ≤ ai < 230). Each of the next m lines contains queries. The i-th line contains integers pi, bi (1 ≤ pi ≤ 2n, 0 ≤ bi < 230) — the i-th query.

Output

Print m integers — the i-th integer denotes value v for sequence a after the i-th query.

Examples
input
Copy
2 4
1 6 3 5
1 4
3 4
1 2
1 2
output
Copy
1
3
3
3
Note

For more information on the bit operations, you can follow this link: http://en.wikipedia.org/wiki/Bitwise_operation

题意:

给出2的n次方个数,每次将现在这个序列中相邻的两个数运算后合并为一个数,得到一个新的序列,这个新序列的长度是上一个序列长度-1,当新序列长度为1时停止运算,奇数次操作进行OR运算,偶数次操作进行XOR运算,
现在有m个询问,每次询问会改变上一个序列中的一个值,问新序列运算后的值为多少

思路:

树上的每一层是一个新序列,从叶子节点那一层记为0,向上更新层数,每层的层数是它下面那层的层数+1
记录了层数之后就知道每一层要进行什么计算了,奇数层OR,偶数层XOR,
最后对每次询问单点修改,向上更新后输出根节点的值就可以了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int amn=1<<17+5;
 4 typedef long long ll;
 5 int a[amn];
 6 struct tree
 7     ll l,r,sum,deep;
 8     #define ls rt<<1
 9     #define rs rt<<1|1
10     #define trl tr[rt].l
11     #define trr tr[rt].r
12     #define trsum tr[rt].sum
13     #define trlssum tr[ls].sum
14     #define trrssum tr[rs].sum
15     #define trdp tr[rt].deep
16 tr[amn];
17 void push_up(int rt)
18     trdp=tr[ls].deep+1;     ///记录计算层数,叶子节点设为0,父节点的层数为儿子节点层数+1
19     if(trdp&1)              ///奇数层数OR运算,偶数层数XOR运算
20         trsum=trlssum|trrssum;
21     else
22         trsum=trlssum^trrssum;
23 
24 void build(int rt,int l,int r)
25     trl=l,trr=r;
26     if(trl==trr)
27         trsum=a[l];
28         trdp=0;             ///叶子节点计算层数
29         return ;
30     
31     int mid=(l+r)>>1;
32     build(ls,l,mid);
33     build(rs,mid+1,r);
34     push_up(rt);
35 
36 void updata(int rt,int l,int r,int pos,ll val)
37     int mid=(l+r)>>1;
38     if(trl==trr&&trl==pos)
39         trsum=val;
40         return;
41     
42     if(pos<=mid)updata(ls,l,mid,pos,val);
43     else updata(rs,mid+1,r,pos,val);
44     push_up(rt);
45 
46 int main()
47     int n,m,p,b;
48     ios::sync_with_stdio(0);
49     cin>>n>>m;
50     int len=1<<n;           ///注意这里长度为2的n次方
51     for(int i=1;i<=len;i++)
52         cin>>a[i];
53     build(1,1,len);
54     while(m--)
55         cin>>p>>b;
56         updata(1,1,len,p,b);
57         printf("%d\n",tr[1].sum);
58     
59 
60 /***
61 给出2的n次方个数,每次将现在这个序列中相邻的两个数运算后合并为一个数,得到一个新的序列,这个新序列的长度是上一个序列长度-1,当新序列长度为1时停止运算,奇数次操作进行OR运算,偶数次操作进行XOR运算,
62 现在有m个询问,每次询问会改变上一个序列中的一个值,问新序列运算后的值为多少
63 在纸上模拟可以看出这是一个完全二叉树的结构,单点修改,向上更新数值,可以想到用线段树来维护
64 树上的每一层是一个新序列,从叶子节点那一层记为0,向上更新层数,每层的层数是它下面那层的层数+1
65 记录了层数之后就知道每一层要进行什么计算了,奇数层OR,偶数层XOR,
66 最后对每次询问单点修改,向上更新后输出根节点的值就可以了
67 ***/

 

以上是关于[线段树]Codeforces 339D Xenia and Bit Operations的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1150E(树线段树)

Codeforces 444C DZY Loves Colors(线段树)

Codeforces 1107G 线段树最大子段和 + 单调栈

CodeForces - 960F Pathwalks —— 主席树(n棵线段树)

Codeforces 786B - Legacy(线段树优化建图)

Codeforces 755D(思维+线段树)