Sumdiv
题意:对A的B次方的所有约数之和mod 9901
思路:对A分解质因数 A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 其中pi均为素数;
所以 A^B = p1^(k1*B) * p2^(k2*B) *...* pn^(kn*B);根据乘法分配律,A^B的所有约数之和为 [1+p1+p1^2+...+p1^(a1*B)] * [1+p2+p2^2+...+p2^(a2*B)] *...*[1+pn+pn^2+...+pn^(an*B)].
考虑到等比数列求和,但是因为要取模而且等比数列求和有除法,所以换一种思路,用分治法进行等比数列求和
1)若n为奇数,一共有偶数项,则:
1 + p + p^2 + p^3 +...+ p^n
= (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))
n为偶数则类似。
#include <cstdio>
#include <iostream>
#include <math.h>
using namespace std;
typedef long long ll;
ll mod = 9901;
ll a, b;
ll power(ll a, ll b)
{
ll ans = 1;
for(; b; b >>= 1)
{
if(b & 1)ans = ans * a % mod;
a = a * a % mod;
}
return ans;
}
ll sum(ll p, ll c)
{
if(c == 0) return 1;
if(c % 2 == 1) return (1 + power(p, (c + 1) / 2)) * sum(p, (c - 1) / 2) % mod;
return ((1 + power(p, c / 2)) * sum(p, c / 2 - 1) + power(p, c)) % mod;
}
int main()
{
// freopen("in.txt", "r", stdin);
cin >> a >> b;
ll pn[10000];
ll pk[10000];
ll len = sqrt(a * 1.0);
ll cnt = 0;
for(int i = 2; i <= len; i++)
{
if(a % i == 0)
{
pn[cnt] = i;
pk[cnt] = 0;
while(a % i == 0)
{
a /= i;
pk[cnt]++;
}
cnt++;
}
}
if(a != 1)
{
pn[cnt] = a;
pk[cnt] = 1;
cnt++;
}
for(int i = 0; i < cnt; i++)
{
pk[i] *= b;
}
ll ans = 1;
for(int i = 0; i < cnt; i++)
{
ans = ans * sum(pn[i], pk[i]) % mod;
}
cout << ans << endl;
return 0;
}