[线段树]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 ***/

 

转载于:https://www.cnblogs.com/Railgun000/p/11367587.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值