题意:求a^b mod 9901 (0 <= A,B <= 50000000)
用到了二分求等比数列和
#include
<
iostream
>
using namespace std;
#define MAXN 7100
int prim[MAXN],pcnt;
bool is_prim[MAXN];
void prepare(){
__int64 i,j;
pcnt = 0 ;
memset(is_prim, true , sizeof (is_prim));
for (i = 2 ;i < MAXN;i ++ ){
if (is_prim[i]){
for (j = i;i * j < MAXN;j ++ )
is_prim[i * j] = false ;
prim[pcnt ++ ] = i;
}
}
}
__int64 exp_mod(__int64 A,__int64 B,__int64 M){
__int64 d = 1 ,bit[ 100 ],k = 0 ,i;
while (B){
bit[k ++ ] = B % 2 ;
B /= 2 ;
} // (bit[k],bit[k-1],,bit[1],bit[0])是B的二进制表示
for (i = k - 1 ;i >= 0 ;i -- ){
d = d * d % M;
if (bit[i] == 1 )
d = d * A % M;
}
return d;
}
__int64 sum(__int64 p,__int64 k){ // 1+p+p^2++p^(k-1)
if (k == 1 )
return 1 ;
__int64 t = sum(p,k / 2 );
if ((k & 1 ) == 1 )
return (( 1 + exp_mod(p,k / 2 + 1 , 9901 )) * t % 9901 + exp_mod(p,k / 2 , 9901 )) % 9901 ;
else
return ( 1 + exp_mod(p,k / 2 , 9901 )) * t % 9901 ;
}
int main(){
prepare();
__int64 a,b,ans,i,j;
while (scanf( " %I64d%I64d " , & a, & b) != EOF){
ans = 1 ;
// b%=9901;
for (i = 0 ;i < pcnt && prim[i] * prim[i] < a && a > 1 ;i ++ ){
for (j = 0 ;a % prim[i] == 0 ;j ++ )
a /= prim[i];
if (j)
ans = ans * sum(prim[i],j * b + 1 ) % 9901 ;
}
if (a > 1 || i == pcnt)
ans = ans * sum(a,b + 1 ) % 9901 ;
printf( " %I64d\n " ,ans);
}
return 0 ;
}
using namespace std;
#define MAXN 7100
int prim[MAXN],pcnt;
bool is_prim[MAXN];
void prepare(){
__int64 i,j;
pcnt = 0 ;
memset(is_prim, true , sizeof (is_prim));
for (i = 2 ;i < MAXN;i ++ ){
if (is_prim[i]){
for (j = i;i * j < MAXN;j ++ )
is_prim[i * j] = false ;
prim[pcnt ++ ] = i;
}
}
}
__int64 exp_mod(__int64 A,__int64 B,__int64 M){
__int64 d = 1 ,bit[ 100 ],k = 0 ,i;
while (B){
bit[k ++ ] = B % 2 ;
B /= 2 ;
} // (bit[k],bit[k-1],,bit[1],bit[0])是B的二进制表示
for (i = k - 1 ;i >= 0 ;i -- ){
d = d * d % M;
if (bit[i] == 1 )
d = d * A % M;
}
return d;
}
__int64 sum(__int64 p,__int64 k){ // 1+p+p^2++p^(k-1)
if (k == 1 )
return 1 ;
__int64 t = sum(p,k / 2 );
if ((k & 1 ) == 1 )
return (( 1 + exp_mod(p,k / 2 + 1 , 9901 )) * t % 9901 + exp_mod(p,k / 2 , 9901 )) % 9901 ;
else
return ( 1 + exp_mod(p,k / 2 , 9901 )) * t % 9901 ;
}
int main(){
prepare();
__int64 a,b,ans,i,j;
while (scanf( " %I64d%I64d " , & a, & b) != EOF){
ans = 1 ;
// b%=9901;
for (i = 0 ;i < pcnt && prim[i] * prim[i] < a && a > 1 ;i ++ ){
for (j = 0 ;a % prim[i] == 0 ;j ++ )
a /= prim[i];
if (j)
ans = ans * sum(prim[i],j * b + 1 ) % 9901 ;
}
if (a > 1 || i == pcnt)
ans = ans * sum(a,b + 1 ) % 9901 ;
printf( " %I64d\n " ,ans);
}
return 0 ;
}