CF653G Move by Prime gxy001

考虑一个问题,给定一个长为 $n$ 的 $01$ 序列,定义一次操作可以把一个位置取反,一个序列的权值为使得序列内数全部相同的最少操作次数,$f_x$ 为有 $x$ 个 $1$ 的序列的所有子序列的权值和。

我们枚举值域内的所有素数幂,设原序列内存在 $c$ 个数为该素数幂的倍数,则答案为 $\sum f_c$,正确性显然。

考虑 $f_x$ 的计算。 \(\begin{aligned} f_x=&\sum\limits_{i=0}^x\sum\limits_{j=0}^{n-x}\binom{x}{i}\binom{n-x}{j}\min(i,j)\\ =&\sum\limits_{t=1}^{\infin}\sum\limits_{i=t}^{\infin}\sum\limits_{j=t}^{\infin}[u^xv^{n-x}]\sum\limits_{a=i}^{\infin}\binom{a}{i}u^a\sum\limits_{b=j}^{\infin}\binom{b}{j}v^b\\ =&[u^xv^{n-x}]\sum\limits_{t=1}^{\infin}\sum\limits_{i=t}^{\infin}\sum\limits_{j=t}^{\infin}\frac{u^i}{(1-u)^{i+1}}\frac{v^j}{(1-v)^{j+1}}\\ =&[u^xv^{n-x}]\sum\limits_{t=1}^{\infin}\frac{u^t}{(1-u)^{t+1}}\frac{v^t}{(1-v)^{t+1}}\sum\limits_{i=0}^{\infin}\frac{u^i}{(1-u)^i}\sum\limits_{j=0}^{\infin}\frac{v^j}{(1-v)^j}\\ =&[u^xv^{n-x}]\sum\limits_{t=1}^{\infin}\frac{u^t}{(1-u)^{t+1}}\frac{v^t}{(1-v)^{t+1}}\frac{1}{1-\frac{u}{1-u}}\frac{1}{1-\frac{v}{1-v}}\\ =&[u^xv^{n-x}]\frac{uv}{(1-2u)(1-2v)(1-u)(1-v)}\sum\limits_{t=0}^{\infin}\frac{u^tv^t}{(1-u)^t(1-v)^t}\\ =&[u^xv^{n-x}]\frac{uv}{(1-2u)(1-2v)(1-u)(1-v)}\frac{1}{1-\frac{uv}{(1-u)(1-v)}}\\ =&[u^xv^{n-x}]\frac{uv}{(1-2u)(1-2v)(1-u-v)}\\ =&[u^xv^n]\frac{uv^2}{(1-2uv)(1-2v)(1-uv-v)}\\ =&[u^xv^n]\frac{uv^2}{(1-u)^2}\left(\frac{2u^2}{1-2uv}+\frac{2}{1-2v}-\frac{(1+u)^2}{1-uv-v}\right) \end{aligned}\)

温馨提示,最后一步的分式分解可能不是人能手算出来的。

我们依次考虑三部分的取值。

\[\begin{aligned} &2[u^{x-3}v^{n-2}]\frac{1}{(1-u)^2(1-2uv)}\\ =&2[u^{x-3}v^{n-2}]\frac{1}{(1-u)^2}\sum\limits_{i=0}^{\infin}(2uv)^i\\ =&2[u^{x-3}]\frac{1}{(1-u)^2}(2u)^{n-2} \end{aligned}\]

因为 $x\le n$,$x-3<n-2$,所以这一项是 $0$。

\[\begin{aligned} &2[u^{x-1}v^{n-2}]\frac{1}{(1-u)^2}\frac{1}{1-2v}\\ =&2[u^{x-1}v^{n-2}]\frac{1}{(1-u)^2}\sum\limits_{i=0}^{\infin}(2v)^i\\ =&2^{n-1}[u^{x-1}]\frac{1}{(1-u)^2}\\ =&2^{n-1}x \end{aligned}\] \[\begin{aligned} &[u^{x-1}v^{n-2}]\frac{(1+u)^2}{(1-u)^2(1-v(1+u))}\\ =&[u^{x-1}v^{n-2}]\frac{(1+u)^2}{(1-u)^2}\sum\limits_{i=0}^{\infin}(v(1+u))^i\\ =&[u^{x-1}]\frac{(1+u)^n}{(1-u)^2}\\ =&\sum\limits_{i=0}^{x-1}\binom{n}{i}(x-1-i+1)\\ =&x\sum\limits_{i=0}^{x-1}\binom{n}{i}-\sum\limits_{i=0}^{x-1}i\binom{n}{i} \end{aligned}\]

所以 $f_x=2^{n-1}x-x\sum\limits_{i=0}^{x-1}\binom{n}{i}+\sum\limits_{i=0}^{x-1}i\binom{n}{i}$,我们可以在 $O(n)$ 的复杂度内求解出所有 $f_x$。

总复杂度为 $O(n\log\log n)$,复杂度瓶颈在于求出素数幂倍数的数量。

感谢 EI 和 GuidingStar 帮忙推式子。

#include<cstdio>
#include<algorithm>
int const mod=1e9+7;
int pow(int x,int y){
	int res=1;
	while(y){
		if(y&1) res=1ll*res*x%mod;
		y>>=1,x=1ll*x*x%mod;
	}
	return res;
}
int n,a[300010],m,p[300010],np[300010],cnt,ans,f[300010],fac[300010],ifac[300010];
int main(){
	scanf("%d",&n);
	for(int i=1,x;i<=n;i++)scanf("%d",&x),m=std::max(x,m),a[x]++;
	for(int i=2;i<=m;i++){
		if(!np[i]) p[++cnt]=i;
		for(int j=1;i*p[j]<=m;j++){
			np[i*p[j]]=1;
			if(i%p[j]==0) break; 
		}
	}
	f[0]=1;
	for(int i=1;i<n;i++) f[0]=f[0]*2%mod;
	for(int i=1;i<=n;i++) f[i]=1ll*f[0]*i%mod;f[0]=0;
	fac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
	ifac[n]=pow(fac[n],mod-2);
	for(int i=n;i;i--) ifac[i-1]=1ll*ifac[i]*i%mod;
	for(int i=0,k=0,q=0;i<n;i++){
		k=(k+1ll*fac[n]*ifac[i]%mod*ifac[n-i])%mod;
		q=(q+1ll*i*fac[n]%mod*ifac[i]%mod*ifac[n-i])%mod;
		f[i+1]=(f[i+1]-(i+1ll)*k%mod+q+mod)%mod;
	}
	for(int i=1;i<=cnt;i++){
		long long q=p[i];
		while(q<=m){
			int cnt=0;
			for(int j=q;j<=m;j+=q) cnt+=a[j];
			ans=(ans+f[cnt])%mod;
			q*=p[i];
		}
	}
	printf("%d\n",ans);
	return 0;
}