题解 CF757E 【Bash Plays with Functions】
STDquantum · · 题解
虽然已经有题解了,我就讲得详细一点,做一下对上一篇的补充吧。
把题中
首先观察
由于
由算术基本定理,有
(
那么对于每个
也就是说
对于形如
由此可以得到
其取值如下(其实前两个都可以通过第三个推导出来,但是由于后文要用到,所以单列出来):
然后再来看
乍一看无从下手,可以尝试将其展开。
由于
又可以发现每个
发现这是一个狄利克雷卷积的形式,若有
推出了
只有一个质因子的时候
这样考虑计算答案也是没问题的,因为
所以现在问题就变成了如何计算出
由定义可知
第二维大小:
#include <bits/stdc++.h>
using namespace std;
namespace STDquantum {
template <typename T> inline void read(T &x) {
char ch;
while (ch = getchar(), ch > '9' || ch < '0') {}
x = (ch ^ 48);
while (ch = getchar(), ch >= '0' && ch <= '9')
x = x * 10 + (ch ^ 48);
}
template <typename T> inline void write(T x) {
static int stk[100], top = 0;
if (x == 0) return (void)putchar('0');
if (x < 0) x = -x, putchar('-');
while (x) stk[++top] = x % 10, x /= 10;
while (top) putchar(stk[top--] + '0');
}
typedef long long ll;
const int N = 1e6 + 10, K = 20, mod = 1e9 + 7;
int low[N];
void getPrime() { // 直接筛质数分解n会T飞,所以记录n的最大质因子
for (int i = 2; i < N; ++i) {
if (!low[i]) {
for (int j = i; j < N; j += i) { low[j] = i; }
}
}
}
int dp[N][K], sum[K] = {1}; // sum[0]是一
void init() {
getPrime();
for (int i = 0; i < N; ++i) { dp[i][0] = 1; }
for (int i = 1; i < K; ++i)
dp[0][i] = 2, sum[i] = sum[i - 1] + dp[0][i];
for (int i = 1; i < N; ++i) {
for (int j = 1; j < K; ++j) {
dp[i][j] = sum[j];
sum[j] = (sum[j - 1] + dp[i][j]) % mod; // 前缀和
}
}
}
int r, n, q;
ll ans = 1;
inline void main() {
init();
for (read(q); q--; ans = 1) {
read(r), read(n);
int cnt, p;
while (n != 1) {
cnt = 0, p = low[n];
while (n % p == 0) ++cnt, n /= p;
ans = ans * dp[r][cnt] % mod;
}
write(ans), putchar('\n');
}
}
} // namespace STDquantum
int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
freopen("D:\\OI\\STDquantum\\test.in", "r", stdin);
freopen("D:\\OI\\STDquantum\\test.out", "w", stdout);
#endif
#ifndef LOCAL
freopen("CF757E_Bash_Plays_with_Functions.in", "r", stdin);
freopen("CF757E_Bash_Plays_with_Functions.out", "w", stdout);
#endif
#endif
STDquantum::main();
return 0;
}