题目链接
题目
思路
最开始的思路:
把A拆成 (a_1 imes a_2) , 那么(A^B) 就变成了(a_1^B imes a_2^B) ,那么(a1)和(a2)能提供的因子(约数)有:
(a_1^0) , (a_1^1) , (a_1^2) (cdots a_1^B)
(a_2^0) , (a_2^1) , (a_2^2)(cdots a_2^B)
还有:
(a_1^0 imes a_2^0) ,(a1^0 imes a2^1),(a_1^0 imes a_2^2)(cdots)
(a_1^1 imes a_2^0),(a_1^1 imes a_2^1),(a_1^1 imes a_2^2)(cdots)
(cdots)(cdots)(cdots)
用一个map记录是否出现过这个因子,然后计算约数和
但(A , B)范围在(5^7)所以必然T了
后来的思路:
一个数的因子,要么是质数,要么是数个质数的乘积
那么我把一个数拆成一堆的质因子相乘,这个数的所有约数都是由这些质因子转化来的
对任意数(x) , 根据唯一分解定理有:
(x = p_1 ^{x_1} imes p_2 ^{x_2} imes p_3 ^{x_3}ldots imes p_m ^{x_m})
也就是说(x)的某个因子(v = p_1 ^{i_1} imes p_2 ^{i_2} imes p_3 ^{i_3}ldots imes p_m ^{i_m})
然后问让你求所有因子的和也就是求:
$sum = (p_1 ^0 + p_1 ^{1} + p_1 ^{2}ldots+ p_1 ^{x_1}) imes (p_2 ^0 + p_2 ^{1} + p_2 ^{2}ldots+ p_1 ^{x_2}) imesldots imes(p_m ^0 + p_m ^{1} + p_m ^{2}ldots+ p_m ^{x_m}) $
为什么是这个公式,举个栗子:
(A = 30 , B = 2)
(A = 2^1 imes 3^1 imes 5^1)
(A^B = (2^1 imes 3^1 imes 5^1)^B = 2^B imes 3^B imes 5^B = 2^2 imes 3^2 imes 5^2)
对于质因子(2)来说:
(2^0)对答案的贡献是:(2^0 imes (3^0 imes 5^0 + 3^0 imes 5^1 + 3^0 imes 5^2 + 3^1 imes 5^0 +ldots +3^2 imes 5^2) = 2^0 imes(3^0 + 3^1 + 3^2) imes (5^0 + 5^1 + 5^2))
同理:(2^1)对答案的贡献是$ 2^1 imes(3^0 + 3^1 + 3^2) imes (5^0 + 5^1 + 5^2)$
等等等等(...)
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define pb(a) push_back(a)
#define fi first
#define se second
#define mp(a , b) make_pair(a , b)
using namespace std;
ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}//xμ?n′?·?mod
const int mod = 9901;
vector< pair<int , int> > vec;
signed main()
{
int a , b;
cin >> a >> b;
if(a == 0)return cout << "0
" , 0;
else if(b == 0) return cout << "1
" , 0;
for(int i = 2 ; i * i <= a ; i ++){
if(a % i == 0){
int cnt = 0;
while(a % i == 0) a /= i , cnt ++;
vec.pb(mp(i , cnt));
}
}
if(a != 1) vec.pb(mp(a , 1));
int ans = 1;
for(int i = 0 ; i < vec.size() ; i ++){
int now = (pow_mod(vec[i].fi , (b * vec[i].se) + 1 % mod , mod) - 1) * pow_mod(vec[i].fi - 1 , mod - 2 , mod);
if(vec[i].fi % mod == 1) now = vec[i].se * (b * vec[i].fi) % mod + 1 % mod;
ans *= now % mod , ans %= mod;
}
cout << (ans % mod + mod) % mod << '
';
return 0;
}