1. 程式人生 > 實用技巧 >CF1139D Steps to One

CF1139D Steps to One

時隔好久終於做掉了這道題

首先我們對於這種問題用常用套路分析(經典輪次期望轉化套路):

\[E(X)=\sum _{i\ge 1} P(X\ge i) \]

這就意味著我只要求長度大於等於\(i\)時的概率,而這個概率顯然可以轉化成長度為\(i-1\)\(\gcd\ne 1\)的概率

考慮總方案數是\(m^{i-1}\)容易得到,因此我們只需要求出長度為\(i-1\)\(\gcd= 1\)的方案數即可

考慮使用容斥,我們列舉\(\gcd=j\),然後真正的\(\gcd|j\)的情況都會被計算,因此方案數是\(\lfloor \frac{m}{j}\rfloor ^{i-1}\)

然後容斥係數是什麼呢,這裡很顯然就是莫比烏斯函式

那麼現在的式子就是:

\[1+\sum_{i\ge 2} \frac{m^{i-1}-\sum_{j=1}^m \mu(j)\lfloor\frac{m}{j}\rfloor^{i-1}}{m^{i-1}}\\ 1+\sum_{i\ge 1} \frac{m^{i}-\sum_{j=1}^m \mu(j)\lfloor\frac{m}{j}\rfloor^{i}}{m^{i}}\\ \]

\(j=1\)\(\mu(j)\lfloor\frac{m}{j}\rfloor^{i}=m^i\)可以單獨提出來和前面的消掉,因此現在式子:

\[1-\sum_{i\ge 1} \frac{\sum_{j=2}^m \mu(j)\lfloor\frac{m}{j}\rfloor^{i}}{m^i}\\ 1-\sum_{j=2}^m \mu(j)\sum_{i\ge 1} (\frac{\lfloor\frac{m}{j}\rfloor}{m})^i \]

後面的\(\frac{\lfloor\frac{m}{j}\rfloor}{m}\)顯然是小於\(1\)的,直接套等比數列求和公式就有:

\[1-\sum_{j=2}^m \mu(j)\frac{\frac{\lfloor\frac{m}{j}\rfloor}{m}}{1-\frac{\lfloor\frac{m}{j}\rfloor}{m}}\\ 1-\sum_{j=2}^m \mu(j)\frac{\lfloor\frac{m}{j}\rfloor}{m-\lfloor\frac{m}{j}\rfloor} \]

然後就可以直接\(O(n\log n)\)做了

Upt:可以通過度教篩可以做到\(O(n^{\frac{2}{3}}+\sqrt n\times \log n)\)

,可以出一個略加強的版本

#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
const int N=100005,mod=1e9+7;
int m,prime[N],mu[N],cnt,ans; bool vis[N];
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
	for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
#define P(x) prime[x]
inline void init(CI n)
{
	RI i,j; for (vis[1]=1,i=2;i<=n;++i)
	{
		if (!vis[i]) prime[++cnt]=i,mu[i]=-1;
		for (j=1;j<=cnt&&i*P(j)<=n;++j)
		{
			vis[i*P(j)]=1; if (i%P(j)) mu[i*P(j)]=-mu[i]; else break;
		}
	}
}
#undef P
int main()
{
	RI i; for (scanf("%d",&m),init(m),ans=1,i=2;i<=m;++i)
	ans=(1LL*ans-(1LL*mu[i]*(m/i)*quick_pow(m-(m/i))%mod+mod)%mod+mod)%mod;
	return printf("%d",ans),0;
}