「数学」约数个数和【难度:NOIP D1T2】求数 n n 的 (所有因数的) 因数个数和。
本人在洛谷发了题解,此处表住不提。事实上部分数据因数极大(诸如 19260817 乘 998244353 此类),Pollad’s Rho 算法无用。以下代码非正解,而是 WinXP 利用数据漏洞的解法。
(由于看不懂正解,暂时留坑)
#include <cstdio>
#include <cstdlib>
#include <algorithm>
typedef long long int LINT;
const LINT MOD = 998244353, MAJC = 64, MAXP = 100000, MAXN = 1000000033;
LINT n, k, jc = 1, zc = 0, inv[MAJC], zs[MAXP], ans = 1; bool hs[MAXP];
LINT Gcd(LINT u, LINT v) { return v? u: Gcd(u % v, v); }
LINT Slp(LINT a, LINT b, LINT m) {
LINT re; if(b == 1) return a % m;
re = Slp(a, b >> 1, m); re = re * re % m;
if(b & 1) return a % m * re % m; else return re; }
inline bool Zsp(LINT u) {
static const LINT AR[12] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
LINT v = u - 1, cnt = 0, j; if(!(u & 1) && u != 2) return false;
while(!(v & 1)) { v >>= 1; cnt++; }
for(int i = 0; i < 12; i++) {
LINT a = std::min(AR[i], u - 2); LINT w = Slp(a, v, u);
if(w == 1 || w == u - 1) continue;
for(j = 1; j < cnt; j++) { w = w * w % u; if(w == u - 1) break; }
if(j == cnt) return false; } return true; }
inline void Wrk(LINT p) {
LINT cnt = 0; LINT re = 1; if(n % p) return;
while(!(n % p)) n /= p, cnt++;
for(int i = 0; i < cnt; i++) re = (cnt + k + 1 - i) % MOD * re % MOD;
ans = re * inv[cnt] % MOD * ans % MOD; }
int main() {
scanf("%lld%lld", &n, &k);
for(int i = 1; i < MAJC; i++) jc = jc * i % MOD;
inv[MAJC - 1] = Slp(jc, MOD - 2, MOD);
for(int i = MAJC - 1; i; i--) inv[i - 1] = i * inv[i] % MOD;
for(int i = 2; i < MAXP; i++) {
if(!hs[i]) zs[zc++] = i;
for(int j = 0; j < zc && i * zs[j] < MAXP; j++) {
hs[i * zs[j]] = true; if(!(i % zs[j])) break; }}
for(int i = 0; i < zc && n != 1; i++) Wrk(zs[i]);
if(n != 1 && Zsp(n)) Wrk(n);
if(n != 1 && !(n % 998244353)) Wrk(998244353);
if(n != 1 && !(n % 1000000007)) Wrk(1000000007);
if(n != 1 && !(n % 1000000009)) Wrk(1000000009);
if(n != 1) ans = inv[1] % MOD * ((2 + k % MOD) % MOD)
% MOD * ans % MOD;
printf("%lld", ans); }