轨道
题目大意
对于以下公式:
已知 和 且 ,问有多少个序列 满足 和 为互质正整数。
注:相同的元素,不同的排列,算不同的方案。
对于 的数据
解题思路
一道好题。
20pts
暴力 ,求出 后 判断 是否为互质正整数即可。
时间复杂度为 ,这不用说了吧。。。
100pts
考虑 DP
。
设 指 的方案数。
那么最终的答案即为 ,其中 满足 k$ 为互质正整数。
但这样做显然空间又大时间又大,所以我们可以换个状态。
由于题意是让 可以整除 且除以 的商与 为互质正整数,所以我们只需关心 \prod\limits_{i = 1}^n a_i k$ 的质因子的个数即可。
因此可以把上述状态优化成如下状态:
设 表示 与 的最大公因数为 的第 个因数的方案总数。
由定义知 除以该公因数的商与 本身互质,否则该数肯定不是最大公因数。1
设 为 的第 个因数。
于是,最终的答案即为 。
再考虑转移方程,根据 的定义,我们需要用前 个数凑出 的倍数,那么不妨用前 个数凑出满足题目条件的 的倍数,再令第 个数为满足题目条件的 的倍数,从而凑出 的倍数。
因为 为 的因数, 又是 的因数,所以 也一定是 的因数。
假设 为 的第 个因数,,即用 个数凑出符合要求的 的倍数的方案总数 符合要求的 的倍数的个数,再求和。
然后再考虑 DP
的边界条件, 即为 中与 的最大公因数为 并且除以 的商与 互质的正整数个数。
假设 是一个符合要求的整数,那么 。
我们可以把这个式子稍微变形一下: 等于 的整数 的个数。
如何维护上面的式子?令 为 的质因数序列。
我们发现 中与 互质的数个数似乎是 减去取值范围内 倍数的个数。
但是这样会重复减去 倍数的个数,因此还需要把它们加回来。
显然这是一个 容斥原理 。
每次容斥的值可以简单地确定:显然我们需要减去所有 的倍数的个数,再加上 的倍数的个数,接着减去 的倍数的个数……
奇数个质因子之积的倍数个数系数应该为 ,反之为 ,这样我们就需要枚举每一种可能的质因数组合,时间复杂度在 的幂次方级别。
时间复杂度即为 。
AC CODE
#include <bits/stdc++.h>
using namespace std;
const int mod = 10007;
int n, m, k;
int sum, p;
int dp[3007][4007], tar[10000007];
int flen, fac[4007], plen, prime[4007], fact[4007][4007];
void dfs(int dep, int val, int g)
{
if (dep > plen)
{
sum += (p / val * g);
return;
}
dfs(dep + 1, val, g);
dfs(dep + 1, val * prime[dep], -g);
}
signed main()
{
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i * i <= k; i++)
if (k % i == 0)
{
fac[++flen] = i;
if (k / i != i)
fac[++flen] = k / i;
}
sort(fac + 1, fac + flen + 1);
int val = k;
for (int i = 2; i * i <= k; i++)
{
if (val % i == 0)
{
prime[++plen] = i;
while (val % i == 0)
val /= i;
}
}
if (val != 1)
prime[++plen] = val;
sort(prime + 1, prime + plen + 1);
for (int i = 1; i <= flen; i++)
{
tar[fac[i]] = i;
sum = 0;
p = m / fac[i];
dfs(1, 1, 1);
dp[1][i] = sum % mod;
}
for (int i = 1; i <= flen; i++)
for (int j = 1; j <= i; j++)
if (fac[i] % fac[j] == 0)
fact[i][++fact[i][0]] = j;
for (int i = 2; i <= n; i++)
for (int j = 1; j <= flen; j++)
for (int k = 1; k <= fact[j][0]; k++)
dp[i][j] = (dp[i][j] + dp[i - 1][fact[j][k]] * dp[1][tar[fac[j] / fac[fact[j][k]]]]) % mod;
printf("%d\n", dp[n][flen]);
return 0;
}
Footnotes
-
简证:设该数,即 和 最大公因数为 ,则 , ,由定义得, 为正整数,即 为正整数,又因为 ,所以 只能为 ,。证毕。 ↩
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18122120