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;
}