链接:http://poj.org/problem?id=1845
将A进行质因数分解,则A^B=(p1^k1)*(p2^k2)*...*(pn^kn)
根据公式,所有因子之和为 (1+p1+p1^2+...p1^k1)*(1+p2+p2^2+...p2^k2)*...*(1+pn+pn^2+...+pn^kn)
计算1+p+p^2+...p^n可以利用二分进行加速
当n为奇数时 1+p+p^2+...p^n=(1+p+p^2+...+p^(k/2))*(1+p^(k/2+1))
当n为偶数时 1+p+p^2+...p^n=(1+p+p^2+...+p^(k/2-1))*(1+p^(k/2+1))+p^(k/2)

1 #include <cstdio> 2 #include <iostream> 3 #include <cmath> 4 #include <cstdlib> 5 #include <cstring> 6 #include <algorithm> 7 using namespace std; 8 typedef long long LL; 9 const LL MOD=9901; 10 LL A, B; 11 LL a[100], b[100]; 12 13 LL PM( LL a, LL b )//二分快速冪; 14 { 15 LL rec=1, t=a; 16 while( b ){ 17 if( b&1 ) 18 rec=( rec*t)%MOD; 19 b>>=1; 20 t=(t*t)%MOD; 21 } 22 return rec; 23 } 24 25 LL fuck ( LL p, LL k )//二分求 p^0+p^1+……p^k, 不能用幾何級數求和公式直接求 26 { 27 if( k==0 ) 28 return 1; 29 if( k&1) 30 return ( 1+PM( p, k/2+1 ))*fuck( p, k/2 ) %MOD; 31 else 32 return (( 1+PM( p, k/2+1 ))*fuck( p, k/2-1 ) %MOD + PM( p,k/2 ))%MOD; 33 } 34 int main( ) 35 { 36 while( scanf( "%lld%lld", &A, &B )==2 ){ 37 int k=0; 38 for( LL i=2; i*i<=A; ++ i ){ 39 if( A%i==0 ){ 40 a[k]=i; 41 b[k]=1; 42 A/=i; 43 while(A%i==0){ 44 A/=i; 45 b[k]++; 46 } 47 k++; 48 } 49 } 50 if( A!=1 ){ 51 a[k]=A; 52 b[k]=1; 53 k++; 54 } 55 LL ans=1; 56 for( int i=0; i<k; ++ i ){ 57 58 ans=( ans*fuck( a[i], b[i]*B))%MOD; 59 } 60 printf( "%lld\n", ans ); 61 } 62 //system( "pause" ); 63 return 0; 64 } 65