μ's [CF 414C Mashmokh and Reverse Operation]

题目
这道题利用的是树形结构的分治性质优化。
准确来说是二叉树的分治

总想一下。分治有两个重要思想:计算独立分组计算

首先来看这题所有的反转都是2^i。(询问不独立!)
这不仅代表了反转的不同种类很少,而且也容易联想到分治,二叉树。
那么就细看反转后对逆序对的影响。
这时,就把思路明确。
因为是分治。所以考虑的应该是两块之间的贡献,树也是如此。考虑的是子树间的贡献。
那么可以发现,反转操作可以拎到二叉树的每层来看。
例如总序列为\([1,2^n]\),那么二叉树有n层。假设当前操作的反转长度为\(2^i\)
那么就从第n-i+1开始。每次把其子树反转,直至递归到第n层。如此实际就完成对序列的\(2^i\)反转。
但是每次反转子树,甚至还是\(O(n\log n)\)。总得就是\(O(mn\log n)\)
因此我们不会真正反转。

因为计算逆序对可以预处理,而反转后的逆序对就是原先的正序对。(类似于归并排序的框架)
而对于每层的一个节点。计算的是其两两子树之间的逆序对数。
无论其上下层如何反转,都不会影响其逆序对数。
所以每个节点的答案就在原序列的逆序对和正序对间变化答案贡献在不同层独立!
这时,其实很明显会发现,同一层中,状态一定相同。要反转一起反转。
答案贡献在同一层分为一组!

所以每次反转就变成了遍历层。维护每层是逆还是正序对。
那么最终时间就是\(O(m\log n)\)

而代码实现时还是要注意小细节。因为预处理是在递归中进行。而求逆序对又要公用树状数组。
所以要注意全局变量的还原处理。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
#define re int
inline int read(){
	int x=0,ff=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')ff=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^'0');c=getchar();}
	return x*ff;
}
int n,m,q,a[(1<<20)+5],d[25],x,c[(1<<20)+5],tot;
long long f[2][25],ans;
int s[(1<<20)+5];
inline int fs(int x){return x&-x;}
inline void add(int x,int y){
	while(x){s[x]+=y;x-=fs(x);}
}
inline int find(int x){int ss=0;
	while(x<=tot){
		ss+=s[x];x+=fs(x);
	}
	return ss;
}
void pre(int i,int l,int r){
	if(l==r)return;
	pre(i-1,l,(l+r)>>1);
	pre(i-1,((l+r)>>1)+1,r);
	for(re j=l;j<=((l+r)>>1);j++)add(a[j],1);
	int x,y;
	for(re j=((l+r)>>1)+1;j<=r;j++){x=find(a[j]+1);y=find(a[j]);f[0][i]+=x;f[1][i]-=y;}
	for(re j=l;j<=((l+r)>>1);j++)add(a[j],-1);
	f[1][i]+=(1ll<<(i*2-2));
}
int main(){
	n=read();
	for(re i=1;i<=(1<<n);i++)a[i]=read(),c[++tot]=a[i];
	sort(c+1,c+tot+1);tot=unique(c+1,c+tot+1)-c-1;
	for(re i=1;i<=(1<<n);i++)a[i]=lower_bound(c+1,c+tot+1,a[i])-c;
	m=read();pre(n,1,(1<<n));
	for(re i=1;i<=n;i++)ans+=f[0][i];
	for(re i=1;i<=m;i++){
		x=read();
		for(re j=x;j;j--){
			d[j]^=1;
			ans+=f[d[j]][j]-f[d[j]^1][j];
		}
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2021-12-05 07:06  sjcx  阅读(53)  评论(0编辑  收藏  举报