CF339D
题目简化与分析:
题目翻译说的还是太复杂了,其实只是给你 $ n $ 个数,奇数位 \(\operatorname{or}\),偶数位 \(\operatorname{xor}\)。
- 会修改某个元素
- 查询修改后运算值
那我们很快就能想到线段树。
毕竟这是个板子。
与普通的板子不一样的就是,加和变成了或或异或。
Solution:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=2e5+50;
const int M=1e5+50;
const int Mod=1e9+7;
inline ll read(){
ll x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
ll n,m;
ll a[N<<2],deep[N<<2];
ll ans[N<<2];
ll ls(int x){return x<<1;}
ll rs(int x){return x<<1|1;}
void push_up(int p){
if(deep[p]&1){
ans[p]=ans[ls(p)]|ans[rs(p)];
}else{
ans[p]=ans[ls(p)]^ans[rs(p)];
}
}
void build(ll p,ll l,ll r){
if(l==r){ans[p]=a[l];return;}
ll mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
deep[p]=deep[ls(p)]+1;
push_up(p);
}
void update(ll nx,ll ny,ll l,ll r,ll p,ll k){
if(nx<=l&r<=ny){
ans[p]=k;
return;
}
ll mid=(l+r)>>1;
if(nx<=mid) update(nx,ny,l,mid,ls(p),k);
if(ny>mid) update(nx,ny,mid+1,r,rs(p),k);
push_up(p);
}
int main()
{
n=read(),m=read();
n=(1<<n);
for(int i=1;i<=n;++i) a[i]=read();
build(1,1,n);
for(int i=1;i<=m;++i){
ll x,y;
x=read(),y=read();
update(x,x,1,n,1,y);
printf("%lld\n",ans[1]);
}
return 0;
}

浙公网安备 33010602011771号