pku1845 Sumdiv

题意:求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 > 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 ;
}
            

转载于:https://www.cnblogs.com/zgmf_x20a/archive/2008/12/03/1346330.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值