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  

你可能感兴趣的:(div)