CodeForces - 1097D:Makoto and a Blackboard (积性)

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 PQ

where P and Q are coprime integers and Q≢0(mod109+7). Print the value of PQ1 modulo 109+7

.

Input

The only line of the input contains two integers n

and k (1n1015, 1k104

).

Output

Print a single integer — the expected value of the number on the blackboard after k

steps as PQ1(mod109+7) for P, Q

defined above.

Examples
Input
6 1
Output
3
Input
6 2
Output
875000008
Input
60 5
Output
237178099

题意:开始给定一个数N,然后让你K轮如下操作:等概率的变为当前数的一个因子,求期望。

思路:发现有点像孟德尔定律的数据,其实就是在暗示我们:豌豆的几种颜色可以单独算,然后作乘。

事实上就是这样的,对于每个素数因子,我们假设他在N中的幂为p(a^p),那么我们可以算出最后幂为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\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hua-dong/p/10223569.html