poj 1845 Sumdiv <数论>

链接: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)

View Code
 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  
posted @ 2012-09-13 16:29  淡墨æ末央  阅读(110)  评论(0编辑  收藏  举报