http://codeforces.com/problemset/problem/1401/F
题意:
解析:
弄一个全局的int:rev来记录所有K的是否翻转(rev与rev之间满足交换律),然后 s w a p ( k ) → r e v e r s e ( k + 1 ) , r e v e r s e ( k ) swap(k)\to reverse(k+1),reverse(k) swap(k)→reverse(k+1),reverse(k)。
查询和单点修改的时候根据rev来转换一下坐标即可。
代码:
/*
* Author : Jk_Chen
* Date : 2020-09-07-09.02.24
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define LD long double
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<"> "<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=(1<<18)+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid (l+r>>1)
#define root int rt,int l,int r
#define lson ls,l,mid
#define rson rs,mid+1,r
int n,num,q;
LL a[maxn];
LL tr[maxn<<2];
int rev;
void build(root){
if(l==r)
tr[rt]=a[l];
else{
build(lson);
build(rson);
tr[rt]=tr[ls]+tr[rs];
}
}
void update(root,int level,int pos,LL val){
if(l==r){
tr[rt]=val;
return;
}
if(rev&1<<level){
pos=l+r-pos;
}
if(pos<=mid)update(lson,level-1,pos,val);
else update(rson,level-1,pos,val);
tr[rt]=tr[ls]+tr[rs];
}
LL query(root,int level,int L,int R){
if(l>=L&&r<=R){
return tr[rt];
}
if(rev&1<<level){
L=l+r-L;
R=l+r-R;
swap(L,R);
}
LL ans=0;
if(L<=mid)
ans=query(lson,level-1,L,R);
if(R>mid)
ans+=query(rson,level-1,L,R);
return ans;
}
void Print(){
return;
rep(i,1,num)
printf("%lld%c",query(1,1,num,n,i,i)," \n"[i==num]);
}
int main(){
n=rd,num=1<<n,q=rd;
rep(i,1,num)
a[i]=rd;
build(1,1,num);
while(q--){
int op=rd;
if(op==1){
int pos=rd,val=rd;
update(1,1,num,n,pos,val);
Print();
}
else if(op==2){
int k=rd;
rev^=1<<k;
Print();
}
else if(op==3){
int k=rd;
rev^=1<<k;
rev^=1<<k+1;
Print();
}
else{
int l=rd,r=rd;
printf("%lld\n",query(1,1,num,n,l,r));
}
}
return 0;
}
/*_________________________________________________________end*/