T2 P1593 因子和
传送门:洛谷P1593
既然要求因子和,那我们就先对 \(a\) 分解质因数,得:
\(a = p_1^{k_1} + p_2^{k_2} + p_3^{k_3}... + p_n^{k_n}\)
所以 \(a^b\) 质因数分解就会得到:
\(a^b = p_1^{k_1*b} + p_2^{k_2*b} + p_3^{k_3*b}... + p_n^{k_n*b}\)
接下来,就是对所有因子求和:
\(ans = (1+p_1^1+p_2^2+p_3^3...p_1^{k_1*b})(1+p_2^1+p_2^2+p_2^3...p_2^{k_2*b})....(1+p_n^1+p_n^2+p_n^3...p_n^{k_n*b})\)
对于上面这个式子,每一个乘数都是一个等比数列,根据等比数列求和公式:
\(sum = \frac{p^n - 1}{p - 1}\)
我们可以用快速幂求出 \(p^n-1\) 因为要对 \(9901\) 取模,所以我们要求 \(p - 1\) 得逆元,\(9901\)是质数,可以用费马小定理求,\(x^{-1} = pow(x, mod - 2)\);
还有一种特殊情况:
- \(p-1\) \(mod\) \(9901 == 0\) 那么 \(p\) \(mod\) \(9901 == 1\),所以 \(sum = 1 + p_1^1 mod9901 + p_2^2mod9901 + ...= 1 + n\)
贴代码:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 5e7 + 5;
const int modl = 9901;
ll p[maxn], k[maxn];
int a, b, cnt;
void Pre() {
int x = a;
for (int i = 2; i <= sqrt(x); ++ i) {
if (x % i) continue ;
p[++ cnt] = i;
while (x % i == 0) {
k[cnt] ++, x /= i;
}
}
if (x != 1) {
p[++ cnt] = x;
k[cnt] ++;
}
}
ll poww(ll a, ll b) {
ll tot = 1;
while (b) {
if (b & 1) tot = a * tot % modl;
a = a * a % modl;
b >>= 1;
}
return tot;
}
void read() {
scanf("%d%d", &a, &b);
if (!a) {
printf("0\n");
return ;
}
Pre();
ll ans = 1, sum = 0;
for (int i = 1; i <= cnt; ++ i) {
k[i] *= b;
if ((p[i] - 1) % modl == 0) {
sum = (k[i] + 1) % modl;
}
else {
ll x = poww(p[i], k[i] + 1) - 1;//如果a等于9901,-1之后会是-1;
ll y = poww(p[i] - 1, modl - 2);
sum = x * y % modl;
}
ans = (ans * sum) % modl;
}
printf("%lld\n", (ans + modl) + modl);//ans有可能是负数;
}
int main() {
read();
return 0;
}
标签:...,14,9901,int,2023.04,sum,T2,maxn
From: https://www.cnblogs.com/florence25/p/17319847.html