Description
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 a1 or a2, a3 or 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 mqueries. 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.
题意:2^n个数字,对于相邻两个数字进行(或运算)或(异或运算),第一次进行(或运算),2^n个数变为2^(n-1)
个数;第二次进行(异或运算),2^(n-1)个数变为2^(n-2)个数;第三次进行(或运算),2^(n-2)个数变为2^(n-3)个
数;第四次进行(异或运算),2^(n-3)个数变为2^(n-4)个数……以此类推,最终得到一个数,该数即为该串数字的
值。每组数据先输入n和m,分别代表有2^n个数和m次询问,接下来有m行,每行有两个数p和b,分别表示将a[p]改
为b,然后输出更改后该串数字的值。
思路:每个数即为线段数的节点,每更改一次,其父节点的值也跟着更改,最终输出根节点的值即可。
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.
Print m integers — the i-th integer denotes value v for sequence a after the i-th query.
2 4
1 6 3 5
1 4
3 4
1 2
1 2
1
3
3
3
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cmath>
using namespace std;
int s[1000100],a[1000100]; //s[]数组用来建树,a[]数组用来记录树的层数
void pushup(int site)
{
a[site]=a[site*2]+1;
if(a[site]%2!=0) //依据题意及自设层数,奇数层就等于下一层进行(或运算)得到的
s[site]=(s[site<<1]|s[site<<1|1]);
else //偶数层就等于下一层进行(异或运算)得到的
s[site]=(s[site<<1]^s[site<<1|1]);
}
void build(int site,int L,int R) //建树
{
if(L==R)
{
a[site]=0; //叶子节点的层数为0
scanf("%d",&s[site]);
return ;
}
int mid=(L+R)/2;
build(site*2,L,mid);
build(site*2+1,mid+1,R);
pushup(site); //更新当前节点的值
}
void update(int site,int L,int R,int l,int val)
{
if(L==R&&L==l)
{
s[site]=val;
return ;
}
int mid=(L+R)/2;
if(mid>=l)
update(site*2,L,mid,l,val);
else
update(site*2+1,mid+1,R,l,val);
pushup(site);
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
int t=pow(2,n);
build(1,1,t); //开始建树
while(m--)
{
int l,val;
scanf("%d %d",&l,&val);
update(1,1,t,l,val);
printf("%d\n",s[1]);
}
}
return 0;
}