Makoto has a big blackboard with a positive integer n written on it. He will perform the following action exactly k
times:
Suppose the number currently written on the blackboard is v
. He will randomly pick one of the divisors of v (possibly 1 and v) and replace v with this divisor. As Makoto uses his famous random number generator (RNG) and as he always uses 58
as his generator seed, each divisor is guaranteed to be chosen with equal probability.
He now wonders what is the expected value of the number written on the blackboard after k
steps.
It can be shown that this value can be represented as P
where P and Q are coprime integers and Q≢0(mod109+7). Print the value of P modulo 109+7
.
InputThe only line of the input contains two integers n
and k (1≤n≤1015, 1≤k≤104).
OutputPrint a single integer — the expected value of the number on the blackboard after k
steps as P for P, Qdefined above.
Examples6 1
3
6 2
875000008
60 5
237178099
题意:开始给定一个数N,然后让你K轮如下操作:等概率的变为当前数的一个因子,求期望。
思路:发现有点像孟德尔定律的数据,其实就是在暗示我们:豌豆的几种颜色可以单独算,然后作乘。
事实上就是这样的,对于每个素数因子,我们假设他在N中的幂为p(a^p,本题当a=2时,p最大为50),那么我们可以算出最后幂为1到p的概率。 而不同素因子之间不会相互影响。
所以我们预处理出开始幂为p,K轮后幂为q的次数mp[p][q];然后就可以对于每个素数得到其概率,然后累乘即可。
(注意不要爆ll
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define ll long long using namespace std; const int maxn=2000010; const int Mod=1e9+7; ll ans,a[maxn],f[maxn],rev[maxn],tot,mp[60][60],M[60][60],sum; int K; int qpow(ll a,int x){ int res=1; while(x){ if(x&1) res=1LL*res*a%Mod; a=1LL*a*a%Mod; x>>=1; } return res; } ll get(int p) { f[p]++; ll tmp=qpow(qpow(f[p],K),Mod-2),res=0; rep(i,1,f[p]) { res=(res+1LL*mp[f[p]][i]*tmp%Mod)%Mod; tmp=tmp*a[p]%Mod; } return res; } void solve(int p) { ll tmp=1; mp[p][p]=1; rep(i,1,K){ rep(j,1,p) M[p][j]=1LL*mp[p][j]*p%Mod,mp[p][j]=0; rep(j,1,p) { rep(k,1,j) mp[p][k]=(mp[p][k]+1LL*M[p][j]*rev[j]%Mod)%Mod; } } } int main() { ll N,tN; scanf("%lld%d",&N,&K); tN=N; rev[0]=1; rep(i,1,51) rev[i]=qpow(i,Mod-2); rep(i,1,51) solve(i); ans=1LL; for(ll i=2;i*i<=tN;i++){ if(tN%i==0){ a[++tot]=i; while(tN%i==0) tN/=i,f[tot]++; sum=sum*(f[tot]+1); } } if(tN>1) a[++tot]=tN,f[tot]=1; rep(i,1,tot) ans=1LL*ans*get(i)%Mod; printf("%lld ",ans); return 0; }