问题 G: 【数论】Sumdiv
求A^B次方的约数之和,
首先对A求约数之和就是
(1 + p1 + p1 ^ 2 + p1 ^ 3 + p1 ^ 4 + … p1 ^ a1) * (1 + p2 + p2 ^ 2 + p2 ^ 3 + p2 ^ 4 + … p2 ^ a2) *… (1 + pk + pk ^ 2 + pk ^ 3 + pk ^ 4 + … pk ^ ak) , 现在是A^B
那么就是求(1 + p1 + p1 ^ 2 + p1 ^ 3 + p1 ^ 4 + … p1 ^ (a1 * B)) * (1 + p2 + p2 ^ 2 + p2 ^ 3 + p2 ^ 4 + … p2 ^ (a2 * B)) *… (1 + pk + pk ^ 2 + pk ^ 3 + pk ^ 4 + … pk ^ (ak * B))
#include <iostream>
using namespace std;
typedef long long ll ;
const int mod = 9901 ;
int p[11001] , n[11001] ;
ll qmi(ll a , ll b )
{
ll res = 1 ;
while(b)
{
if(b & 1) res = res * a % mod ;
a = a * a % mod ;
b >>= 1 ;
}
return res ;
}
ll sum(ll p , ll n)
{
if(n == 0) return 1 ;
if(n % 2 )
return sum(p , n / 2) * (1 + qmi(p , n / 2 + 1)) % mod ;
else
return (sum(p , n / 2 - 1) * (1 + qmi(p , n / 2 + 1)) + qmi(p , n / 2)) % mod ;
}
int main()
{
int a , b ;
while(cin >> a >> b)
{
int k = 0 ;
for(int i = 2 ;i * i <= a ; i ++)
{
if(a % i == 0)
{
p[++ k] = i , n[k] = 0 ;
while(a % i == 0)
n[k] ++ , a /= i ;
}
}
if(a > 1)
p[++ k] = a , n[k] = 1 ;
ll ans = 1 ;
for(int i = 1 ;i <= k ;i ++)
ans = (ans * sum(p[i] , n[i] * b) % mod) % mod ;
cout << ans << endl ;
}
return 0 ;
}
每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。