• 题解-CF1139D Steps to One


    题面

    CF1139D Steps to One

    一个数列,每次随机选一个 ([1,m]) 之间的数加在数列末尾,数列中所有数的 (gcd=1) 时停止,求期望长度 (mod 10^9+7)

    数据范围:(1le mle 10^5)


    蒟蒻语

    这题的非 dp 做法讲得太玄了而且写题解的人貌似不屑于解释/yiw,于是蒟蒻来写一篇。

    (其实是 ubuntu 剪贴板炸了没得记录题目了只好写题解了/wul)。


    蒟蒻解

    先推一波概率期望式((E(x))(x) 的期望,(P(x))(x) 事件的概率)。

    [egin{split} E(len)=&sum_{ige 1}P(len=i)cdot i\ =&sum_{ige 1}P(len=i)sum_{j=1}^i\ =&sum_{jge 1}sum_{ige j}P(len=i)\ =&sum_{ige 1}P(lenge i)\ =&1+sum_{ige 1}P(len>i)\ end{split} ]

    因为 (gcd_{i=1}^{len} a_i=1) 就结束了,所以:

    [egin{split} P(len>i)=&Pleft(left(gcd_{j=1}^{i} a_i ight)>1 ight)\ =&1-Pleft(left(gcd_{j=1}^{i} a_i ight)=1 ight)\ =&1-frac{sum_{a_1=1}^msum_{a_2=1}^mcdotssum_{a_i=1}^mepsilonleft(left(gcd_{j=1}^{i} a_i ight) ight)}{m^i}\ =&^{color{#aa88cc}{(1)}}1-frac{sum_{a_1=1}^msum_{a_2=1}^mcdotssum_{a_i=1}^msum_{d|left(gcd_{j=1}^{i} a_i ight)}mu(d)}{m^i}\ =&1-frac{sum_{d=1}^mmu(d)sum_{a_1=1}^m[d|a_1]sum_{a_2=1}^m[d|a_2]cdotssum_{a_i=1}^m[d|a_i]}{m^i}\ =&1-frac{sum_{d=1}^mmu(d)left(lfloorfrac{m}{d} floor ight)^i}{m^i}\ =&^{color{#eeaa22}{(2)}}-frac{sum_{d=2}^mmu(d)left(lfloorfrac{m}{d} floor ight)^i}{m^i}\ end{split} ]

    (color{#aa88cc}{(1)}) 就是一个莫反,(color{#eeaa22}{(2)}) 就是把 (d=1) 的值和 (1) 抵消掉。

    带回上式:

    [egin{split} E(len)=&1+sum_{ige 1}P(len>i)\ =&1-sum_{ige 1}frac{sum_{d=2}^mmu(d)left(lfloorfrac{m}{d} floor ight)^i}{m^i}\ =&1-sum_{ige 1}frac{1}{m^i}sum_{d=2}^mmu(d)left(lfloorfrac{m}{d} floor ight)^i\ =&1-sum_{d=2}^mmu(d)sum_{ige 1}left(frac{lfloorfrac{m}{d} floor}{m} ight)^i\ =&^{color{#ff2211}{(3)}}1-sum_{d=2}^mmu(d)frac{lfloorfrac{m}{d} floor}{m-lfloorfrac{m}{d} floor}\ end{split} ]

    (color{#ff2211}{(3)}) 是无穷等比数列求值:

    [s=x+x^2+x^3+cdots\ sx=x^2+x^3+x^4+cdots\ s-sx=x\ s=frac{x}{1-x}\ ]

    然后就可以筛个 (mu(i)) 就可以 (Theta(m)) 地算了,当然您可以杜教到 (Theta(m^{frac 23})),但是那么秀有什么意思呢……


    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    //Start
    typedef long long ll;
    typedef double db;
    #define mp(a,b) make_pair((a),(b))
    #define x first
    #define y second
    #define be(a) (a).begin()
    #define en(a) (a).end()
    #define sz(a) int((a).size())
    #define pb(a) push_back(a)
    #define R(i,a,b) for(int i=(a),I=(b);i<I;i++)
    #define L(i,a,b) for(int i=(a),I=(b);i>I;i--)
    const int iinf=0x3f3f3f3f;
    const ll linf=0x3f3f3f3f3f3f3f3f;
    
    //Data
    const int mod=1e9+7;
    
    //Sieve
    struct sieve{
    	int n;
    	vector<bool> np;
    	vector<int> prime,mu,inv;
    	void Sieve(){
    		np[1]=true,mu[1]=1;
    		R(i,2,n){
    			if(!np[i]) prime.pb(i),mu[i]=-1;
    			for(int p:prime){
    				if(!(i*p<n)) break;
    				np[i*p]=true;
    				if(i%p==0){mu[i*p]=0;break;}
    				mu[i*p]=mu[i]*mu[p];
    			}
    		}
    		inv[1]=1;
    		R(i,2,n) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
    	}
    	sieve(int _n){
    		n=_n,np.assign(n,false),inv.resize(n);
    		prime.clear(),mu.resize(n),Sieve();
    	}
    };
    
    //Main
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0),cout.tie(0);
    	int n; cin>>n;
    	sieve math(n+1);
    	int ans=1;
    	R(i,2,n+1) (ans+=mod-1ll*(mod+math.mu[i])%mod
    			   *(n/i)%mod*math.inv[n-n/i]%mod)%=mod;
    	cout<<ans<<'
    '; 
    	return 0;
    }
    

    祝大家学习愉快!

  • 相关阅读:
    IO编程
    File类
    对于Java集合理解
    Java泛型
    多线程编程
    异常处理
    Static.final修饰符、super关键字及常量与变量
    java类的基本结构
    数组
    二叉树后序遍历 递归 非递归
  • 原文地址:https://www.cnblogs.com/George1123/p/13586454.html
Copyright © 2020-2023  润新知