Topic Link: http://poj.org/problem?id=1845
The main idea: Calculate the a^b of all the divisors and the results after 9901 modulo.
Analysis: We know that for a positive integer n, we have n= (p1) ^a1* (p2) ^a2*...* (PK) ^ak, define divisors and functions σ (n) =∏ (pi^ (ai+1)-1)/(pi-1); So for a^b, we have a^b= (p1) ^ (B*A1) * (p2) ^ (B*A2) *...* (PK) ^ (B*ak), its divisors and σ (a^b) =∏ (pi^ (ai+b+1)-1)/(pi-1). For the denominator modulo, we have ans≡a/b (mod m) ==> ans≡a (mod MB)/b.
The implementation code is as follows:
#include <cstdio> #include <cstring> using namespace std;
typedef long Long LL;
const int mod=9901;
const int n=10005;
int p[n],cnt;
BOOL Isp[n];
void Init () {cnt=0;
Memset (isp,true,sizeof (ISP));
for (int i=2;i<n;i++) if (Isp[i]) {p[cnt++]=i;
for (int j=i+i;j<n;j+=i) Isp[j]=false;
} ll multi (ll a,ll b,ll m) {ll ans=0;
A%=m;
while (b) {if (b&1) ans= (ans+a)%m;
b>>=1;
A= (a+a)%m;
return ans;
ll Quick_mod (ll a,ll b,ll m) {ll ans=1;
A%=m;
while (b) {if (b&1) Ans=multi (ans,a,m);
b>>=1;
A=multi (A,A,M);
return ans;
} void Solve (ll a,ll B) {ll ans=1;
for (int i=0;i<cnt&&p[i]*p[i]<=a;i++) {if (a%p[i]==0) {int num=0;
while (a%p[i]==0) {num++;
A/=p[i]; LL m= (p[i]-1) *mod;
Ans*= (Quick_mod (p[i],num*b+1,m)-1)/(P[I]-1);
Ans%=mod;
} if (a>1) {LL m= (A-1) *mod;
Ans*= (Quick_mod (a,b+1,m)-1)/(A-1);
Ans%=mod;
printf ("%i64d\n", ans);
int main () {LL a,b;
Init ();
while (scanf ("%i64d%i64d", &a,&b)!=-1) Solve (a,b);
return 0;
}
For the sum of the geometric progression, we can also use the binary multiplication to do, the specific procedure can refer to: Click on the Open link.
Suppose there are geometric progression 1,a,a^2,..., a^n:
(1) If n is odd, then (n+1) is even, at this time we have:
S (N) =1+a+a^2+...+a^n=1+a+a^2+...+a^ ((n-1)/2) +a^ ((n-1)/2+1) +...+a^ ((n-1)/2+ (n-1)/2) +a^ ((n-1)/2+ (n-1)/2+1) = (1+a^ ((n-1)/2+1) * (1+a+a^2+...+a^ ((n-1)/2) = (1+a^ (n-1)/2+1) *s ((n-1)/2);
(2) If n is an even number, then (n+1) is odd, at this time we have:
S (n) =1+a+a^2+...+a^n=1+a+a^2+...+a^ (n/2-1) +a^ (N/2) +a^ (n/2+1) +...+a^ (N/2+N/2) = (1+a^ (n/2+1) * (1+a+a^2+...+a^ (n/ 2-1) = (1+a^ (n/2+1) *s (n/2-1);
The implementation code is as follows:
#include <cstdio> #include <cstring> using namespace std;
typedef long Long LL;
const int mod=9901;
const int n=10005;
int p[n],cnt;
BOOL Isp[n];
void Init () {cnt=0;
Memset (isp,true,sizeof (ISP));
for (int i=2;i<n;i++) if (Isp[i]) {p[cnt++]=i;
for (int j=i+i;j<n;j+=i) Isp[j]=false;
} ll Quick_mod (ll a,ll b,ll m) {ll ans=1;
A%=m;
while (b) {if (b&1) ans=ans*a%m;
b>>=1;
a=a*a%m;
return ans;
ll Sum (ll a,ll N) {if (n==0) return 1;
if (n&1) {return (1+quick_mod (A, (n-1)/2+1,mod)) * Sum (A, (n-1)/2)%mod)%mod;
else {return ((1+quick_mod (a,n/2+1,mod)) * Sum (a,n/2-1)%mod + quick_mod (a,n/2,mod))%mod;
} void Solve (ll a,ll B) {ll ans=1;
for (int i=0;i<cnt&&p[i]*p[i]<=a;i++) {if (a%p[i]==0) {int num=0;
while (a%p[i]==0) { num++;
A/=p[i];
} ans*=sum (p[i],num*b)%mod;
Ans%=mod;
} if (a>1) {ans*=sum (a,b)%mod;
Ans%=mod;
printf ("%i64d\n", ans);
int main () {LL a,b;
Init ();
while (scanf ("%i64d%i64d", &a,&b)!=-1) Solve (a,b);
return 0;
}