Solución: CF 1401 F \ mathrm {CF1401F}C F 1 4 0 1 F
Significado del tema
S ol \ mathrm {Sol} S o l
Una pregunta ds no difícil
Consideramos poner la secuencia en el árbol del segmento de línea, 2 n 2 ^ n2El número de n es equivalente al número de nodos de hojas del árbol del segmento de línea.
Para 1 ∼ 4 1 \ sim 41∼La operación de 4 también es2, 3 2, 32 ,3 es más difícil de mantener, consideramos2 22 operación, asumiendo eliii nodo estádd en elárbol de segmento de línead capa (1 11 nodo esnnn capa). Entonces, la operación de inversión es equivalente a invertir los hijos izquierdo y derecho de todas las capas de abajo respectivamente, por lo que establecemos0 ∼ d 0 \ sim d0∼Simplemente marque la capa d . Para3 33 operación es equivalente ad + 1 d + 1re+La máquina de marcado de 1 capa puede realizar el intercambio de bloques adyacentes.
Para la capa marcada, podemos hacer la recursividad inversa, y el resto es la suma del intervalo del árbol del segmento de línea.Puede ver la implementación del código para más detalles.
Complejidad temporal O (2 18 × 18) O (2 ^ {18} \ times 18)O ( 21 8×1 8 )
C ode \ mathrm {Código} C o d e
const int mo=998244353;
const int N=1<<18;
int n,m,S,a[N+5],t[N*4+5],flg[21];
inline void Fix(int x,int l,int r,int p,int val,int d)
{
if(p>r||p<l) return;
if(l==r)
{
t[x]=val;
return;
}
int mid=l+r>>1;
if(flg[d]) Fix(x<<1|1,l,mid,p,val,d-1),Fix(x<<1,mid+1,r,p,val,d-1);
else Fix(x<<1,l,mid,p,val,d-1),Fix(x<<1|1,mid+1,r,p,val,d-1);
t[x]=t[x<<1]+t[x<<1|1];
}
inline int Ask(int x,int l,int r,int ll,int rr,int d)
{
if(ll>r||rr<l) return 0;
if(ll<=l&&r<=rr) return t[x];
int mid=l+r>>1;
int ans=0;
if(flg[d]) ans=Ask(x<<1,mid+1,r,ll,rr,d-1)+Ask(x<<1|1,l,mid,ll,rr,d-1);//如果打上标记,那么对于左儿子要在[mid+1,r]里递归下去
else ans=Ask(x<<1,l,mid,ll,rr,d-1)+Ask(x<<1|1,mid+1,r,ll,rr,d-1);
return ans;
}
signed main()
{
io.read(n),io.read(m);
S=(1ll<<n);
For(i,1,S)
{
io.read(a[i]);
Fix(1,1,S,i,a[i],n);
}
for (;m--;)
{
int type,x,y;
io.read(type);
io.read(x);
if((type^2)&&(type^3)) io.read(y);
if(type==1) Fix(1,1,S,x,y,n);
if(type==3) flg[x+1]^=1;
if(type==2) For(i,0,x) flg[i]^=1;
if(type==4) io.write(Ask(1,1,S,x,y,n)),puts("");
}
return 0;
}