• Hello 2019 D 素因子贡献法计算期望 + 概率dp + 滚动数组


    https://codeforces.com/contest/1097/problem/D

    题意

    给你一个n和k,问n经过k次操作之后留下的n的期望,每次操作n随机变成一个n的因数

    题解

    • 概率dp计算出每个素因子留下的概率,乘以这个素因子的值就是这个素因子的贡献期望
    • 定义(dp[i][j])为第i次操作后剩下j个素因子的概率,概率dp顺着推
      • (dp[i][j]->dp[i+1][k](k<=j))
      • (dp[i+1][k]+=dp[i][j]frac{1}{j+1}(k<=j))
    • (ans=sum^{cnt}_{i=1}sum^{num[i]}_{j=0}pr[i]^j*dp[k][j])
    • 二维滚动数组滚掉一维

    代码

    #include<bits/stdc++.h>
    #define P 1000000007
    #define M 32000000
    #define MAXN 100
    #define ll long long 
    using namespace std;
    ll dp[2][MAXN],inv[MAXN],n,ans=1;
    int vi[M],sz,k,pr[M];
    void sieve(){
    	inv[0]=inv[1]=1;
    	for(int i=2;i<MAXN;i++)inv[i]=(P-P/i)*inv[P%i]%P;
    
    	for(ll i=2;i<M;i++){
    		if(!vi[i])pr[++sz]=i;
    		for(int j=1;j<=sz&&pr[j]*i<M;j++){
    			vi[pr[j]*i]=1;
    			if(i%pr[j]==0)break;
    		}
    	}
    }
    
    int main(){
    	sieve();
    	cin>>n>>k;
    	for(int i=1;i<=sz&&pr[i]<=n;i++){
    		int cnt=0;
    		if(n%pr[i])continue;
    		while(n%pr[i]==0){
    			n/=pr[i];
    			cnt++;
    		}
    		memset(dp,0,sizeof(dp));          //
    		dp[0][cnt]=1;
    		int st=0;
    		for(int j=0;j<k;j++){
    			memset(dp[st^1],0,sizeof(dp[st^1]));
    			for(int p=0;p<=cnt;p++){
    				for(int q=0;q<=p;q++){
    					dp[st^1][q]+=dp[st][p]*inv[p+1]%P;
    					dp[st^1][q]%=P;
    				}
    			}
    			st^=1;
    		}
    		ll mul=1,tp=0;
    		for(int j=0;j<=cnt;j++){
    			tp+=dp[st][j]*mul%P;
    			tp%=P;
    			mul=mul*pr[i]%P;
    		}
    		ans=ans*tp%P;                //
    	}
    	if(n>1){
    		memset(dp,0,sizeof(dp));
    		dp[0][1]=1;
    		int st=0;
    		for(int j=0;j<k;j++){
    			memset(dp[st^1],0,sizeof(dp[st^1]));
    			for(int p=0;p<=1;p++){
    				for(int q=0;q<=p;q++){
    					dp[st^1][q]+=dp[st][p]*inv[p+1]%P;
    					dp[st^1][q]%=P;
    				}
    			}
    			st^=1;
    		}
    		ll mul=1,tp=0;
    		for(int j=0;j<=1;j++){
    			tp+=dp[st][j]*mul%P;
    			tp%=P;
    			mul=mul*n%P;
    		}
    		ans=ans*tp%P;
    	}
    	cout<<ans;
    }
    
  • 相关阅读:
    Zookeeper白话解析
    WireMock简单使用
    mysql通用包安装
    修改mysql密码
    jmeter for循环嵌套if学习2
    jmeter for循环嵌套if学习1
    jmeter Transaction Controller学习
    jmeter ForEach Controller学习
    loadrunner随笔1
    shell中创建mysql库和执行sql脚本
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10806133.html
Copyright © 2020-2023  润新知