zoukankan      html  css  js  c++  java
  • 【CF1139D】Steps to One(动态规划)

    【CF1139D】Steps to One(动态规划)

    题面

    CF
    你有一个数组,每次随机加入一个([1,n])的数,当所有数(gcd)(1)时停止,求数组长度的期望。

    题解

    (f[i])表示(gcd)(i)时的答案的期望。
    考虑转移就是每次选一个数和(i)求个(gcd),那么计算一下变成每个可能的值的方案数直接暴力转移就行了。
    复杂度似乎是两个(log)???

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    using namespace std;
    #define MOD 1000000007
    #define MAX 100100
    void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
    int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
    int n,f[MAX],inv[MAX],mu[MAX];
    vector<int> y[MAX];
    int main()
    {
    	scanf("%d",&n);f[1]=0;mu[1]=1;inv[0]=inv[1]=1;
    	for(int i=2;i<=n;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
    	for(int i=1;i<=n;++i)for(int j=i;j<=n;j+=i)y[j].push_back(i);
    	for(int i=1;i<=n;++i)for(int j=i+i;j<=n;j+=i)mu[j]-=mu[i];
    	for(int i=1;i<=n;++i)
    	{
    		int p=n/i;
    		if(i!=1)f[i]=1ll*(f[i]+p)*inv[n-p]%MOD;;
    		add(f[0],f[i]+1);
    		for(int j=i+i;j<=n;j+=i)
    		{
    			int d=j/i,s=0;
    			for(int v:y[d])s+=mu[v]*(p/v);
    			add(f[j],1ll*s*(f[i]+1)%MOD);
    		}
    	}
    	f[0]=1ll*f[0]*inv[n]%MOD;
    	printf("%d
    ",f[0]);
    	return 0;
    }
    
  • 相关阅读:
    [CF600E]Lomsat gelral
    [BZOJ3237]连通图
    [CF580D]Kefa and Dishes
    [BZOJ4726]Sabota?
    bzoj2120&&2453 -- 带修改莫队
    bzoj4726 [ POI2017 ] -- 树形DP
    bzoj2809 [ APIO2012 ] -- 主席树
    bzoj4216 -- 分块
    bzoj4173 -- 欧拉函数
    bzoj2982 -- Lucas定理
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10655396.html
Copyright © 2011-2022 走看看