757E. Bash Plays with Functions 题解
757E. Bash Plays with Functions
题意:定义函数
给定 次询问,每次询问给出 ,输出 答案对 取模
解法:积性函数
首先把柿子化成容易计算的形式,从 开始
将 分解成
那么根据定义,,
由于 ,所以
故 ,注意到其与具体的值无关,只与次数有关。
容易看出 是一个积性函数
可以看出,, 都枚举了两次,故可以进一步化简为
设 为积性函数,接下来证明 也是积性函数
(抱歉不知道如何对齐)
根据数学归纳法, 是积性函数
那么对于任何一次询问,设 ,我们只需要算出 ,然后根据积性函数的性质乘起来即可。
接下来的递推求解即可,注意到函数的值与质数大小无关,只与次数有关,故该函数可以在 的时间内完成
接下来只要对每次询问,分解出 即可,注意到 只有 ,可以预处理下每个数的最小质因子,然后递推回 即可,可以在 的时间内完成,总复杂度为
#include <bits/stdc++.h>
#define endl '\n'
#define ls u << 1
#define rs u << 1 | 1
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL,LL> PLL;
const int INF = 0x3f3f3f3f, N = 1e6 + 10;
const int MOD = 1e9 + 7;
const double eps = 1e-6;
const double PI = acos(-1);
inline int lowbit(int x) {return x & (-x);}
LL f[N][22];
bool st[N];
int last[N], pr[N], num;
void init() {
int n = 1000000;
for (int i = 0; i <= n; i ++ ) f[i][0] = 1;
for (int j = 1; j <= 20; j ++ ) {
for (int i = 0; i <= n; i ++ ) {
if (i == 0) f[i][j] = 2;
else if (i == 1) f[i][j] = 1 + 2 * j;
else for (int k = 0; k <= j; k ++ ) f[i][j] = (f[i][j] + f[i - 1][k]) % MOD;
}
}
for (int i = 2; i <= n; i ++ ) {
if (!st[i]) pr[++ num] = i, last[i] = i;
for (int j = 1; 1ll * pr[j] * i <= n; j ++ ) {
st[i * pr[j]] = true;
last[i * pr[j]] = pr[j];
if (i % pr[j] == 0) break;
}
}
}
inline void solve() {
int r, n; cin >> r >> n;
LL res = 1;
while (n != 1) {
int cnt = 0, p = last[n];
while (n % p == 0) n /= p, cnt ++;
res = res * f[r][cnt] % MOD;
}
cout << res << endl;
}
int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
auto now = clock();
#endif
ios::sync_with_stdio(false), cin.tie(nullptr);
cout << fixed << setprecision(2);
init();
int T; cin >> T;
while (T -- )
solve();
#ifdef DEBUG
cout << "============================" << endl;
cout << "Program run for " << (clock() - now) / (double)CLOCKS_PER_SEC * 1000 << " ms." << endl;
#endif
return 0;
}
标签:
题解
, codeforces