D. Makoto and a Blackboard (dp + desired factorization)

topic

Meaning of the questions:

    Given a n, n mathematical expectation values ​​have equal probability after n it becomes a factor, k output operations for each operation.
     1 n 1 0 15 , 1 k 1 0 4 1≤n≤10^{15} , 1≤k≤10^4

analysis:

    Because of that factor, so we naturally go out into the prime factor decomposition thinking direction. Due to a large number of n, the number of factors that we find it is a very troublesome thing, not to mention also requested factor, too many number of states. In fact, we can break it into prime factors, it does not affect the operation of each prime factor to each other, so for the n operation, it may become a prime factor operation, the desired final prime factors by multiplying.
    DP [i] [j] indicates the i th operation order of the current prime factor for the probability of j, dp [i] [j] can be j && t from dp [i-1] [t ] (t> = < = maximum), multiplied by the probability of the final value. Compare wound needs careful analysis.

#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;

ll mod = 1e9 + 7; 
vector<ll> num,count;
ll dp[10005][60];
ll inv[65];

ll q_pow(ll a,ll b)
{
	ll res = 1;
	while( b )
	{
		if( b & 1 ) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}

void divide(ll n)
{
	ll a = n;
	for (ll i = 2; i * i <= n; i++)
	{
		if( a % i == 0 )
		{
			num.push_back(i);
			int t = 0;
			while( a % i == 0 )
			{
				a /= i;
				t ++;
			}
			count.push_back(t); 
		}
	}
	if( a > 1 )
	{
		num.push_back(a);
		count.push_back(1);  
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	inv[1] = 1;
	for (int i = 2; i <= 60; i++)
	{
		inv[i] = mod - (mod/i) * inv[mod%i] % mod;
	} 
	ll n,k;
	cin >> n >> k;
	divide(n);
	ll ans = 1;
	for (int i = 0; i < num.size(); i++)
	{
		ll temp = 0;
		for (int j = 0; j <= k; j++)
		{
			for (int l = 0; l <= count[i]; l++)
			{
				if( j == 0 ) 
				{
					if( l == count[i] ) dp[j][l] = 1;
					else dp[j][l] = 0;
				}
				else
				{
					dp[j][l] = 0;
					for (int t = l; t <= count[i]; t++)
					{
						dp[j][l] += (dp[j-1][t] * inv[t+1]) % mod;
						dp[j][l] %= mod;
					}
				}
				if( j == k ) temp = (temp + (dp[j][l] * q_pow(num[i],l)) % mod ) % mod;
			}
		}
		ans *= temp;
		ans %= mod;
	}
	cout << ans << '\n';
	return 0;
}

Published 132 original articles · won praise 6 · views 7910

Guess you like

Origin blog.csdn.net/weixin_44316314/article/details/105125600