题意:给你a,b,要求给出a^b的因子和取模9901的结果。
思路:求因子和的方法:任意A = p1^a1 * p2^a2 ....pn^an,则因子和为sum =(1 + p1 + p1^2 + ... . + p1^a1)*(1 + p2 + p2^2 + ... . + p2^a2)*(1 + pn + pn^2 + .... + pn^an)。又由等比数列求和公式可知 1 + pn + pn^2 + .... + pn^an =(pn^an - 1)/(pn - 1)。因为要mod 9901,所以除数取模要用到逆元:A / B mod m = (A mod(B * m))/ B。在快速幂求解过程中会爆过程,所以手动写了乘法。
补充:
任意A = p1^a1 * p2^a2 ....pn^an
因数和:sum =(1 + p1 + p1^2 + ... . + p1^a1)*(1 + p2 + p2^2 + ... . + p2^a2)*(1 + pn + pn^2 + ... . + pn^an)
因数个数:num = (a1 + 1)*(a2 + 1)....(an + 1)
代码:
#include<set> #include<map> #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; const int maxn = 20000 + 10; const int seed = 131; const int MOD = 9901; const int INF = 0x3f3f3f3f; ll mul(ll a, ll b, ll c){ ll ans = 0; while(b){ if(b & 1){ ans = ans + a; if(ans > c) ans -= c; } a = a + a; if(a > c) a -= c; b >>= 1; } return ans; } ll pmul(ll a, ll b, ll c){ a = a % c; ll ans = 1; while(b){ if(b & 1) ans = mul(ans, a, c); a = mul(a, a, c); b >>= 1; } return ans; } int main(){ ll a, b; while(~scanf("%lld%lld", &a, &b)){ ll ans = 1; for(ll i = 2; i * i <= a; i++){ if(a % i == 0){ ll num = 0; while(a % i == 0){ a /= i; num++; } ans *= (pmul(i, b * num + 1, (i - 1) * MOD) - 1) / (i - 1); ans %= MOD; } } if(a > 1){ ans *= (pmul(a, b + 1, (a - 1) * MOD) - 1) / (a - 1); ans %= MOD; } printf("%lld ", ans); } return 0; }