D. Makoto y una pizarra (dp + factorización deseada)

título

Significado de las preguntas:

    Dado un n, n valores esperanza matemática tienen la misma probabilidad después de n se convierte en un factor, operaciones de salida k para cada operación.
     1 norte 1 0 15 , 1 k 1 0 4 1≤n≤10 ^ {15}, 1≤k≤10 ^ 4

análisis:

    Debido a ese factor, por lo que, naturalmente, salir a la dirección pensamiento descomposición factorial. Debido a un gran número de n, el número de factores que nos encontramos con que es una cosa muy molesto, por no mencionar el factor pidió también, demasiados número de estados. De hecho, podemos dividirla en factores primos, que no afecta el funcionamiento de cada factor primordial entre sí, por lo que para la operación n, puede convertirse en un factor primordial operación, los factores primos finales deseados multiplicando.
    DP [i] [j] indica el i-ésimo orden de operación del primer factor actual de la probabilidad de j, dp [i] [j] puede ser j && t de dp [i-1] [t ] (t> = < = máximo), multiplicado por la probabilidad de que el valor final. Comparación de la herida necesita un análisis cuidadoso.

#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;
}

Publicados 132 artículos originales · ganado elogios 6 · vistas 7910

Supongo que te gusta

Origin blog.csdn.net/weixin_44316314/article/details/105125600
Recomendado
Clasificación