Sumdiv--POJ 1845

1、解题思路:数论,大数处理。

2、注意事项:A可以唯一分解成p1^a1*p2^a2*...pi^ai...*pn^an;公式:(A*B)%C=((A%C)*(B%C))%C;中间值全部用__int64表示;利用位运算如:n&1,判断n的奇偶性。

3、实现方法:

  
    
#include < iostream >
#define M 9901
#define MAX 10000
using namespace std;

int A,B,count;
int p[MAX],c[MAX];

// 求解 x^n
__int64 Pow(__int64 x,__int64 n)
{
__int64 ret
= 1 ,s = x;
while ( 1 )
{
if (n & 1 )
ret
= (ret % M * s % M) % M;
if (n >>= 1 )
s
= (s % M * s % M) % M;
else
break ;
}
return ret;
}

// 求解 1+p+p^2+...+p^n 等比数列的求和
__int64 Sum(__int64 p,__int64 n)
{
if (n == 0 )
return 1 ;
if (n & 1 )
return (( 1 + Pow(p,n / 2 + 1 )) % M * Sum(p,n / 2 ) % M) % M;
else
return (( 1 + Pow(p,n / 2 + 1 )) % M * Sum(p,(n - 1 ) / 2 ) % M + Pow(p,n / 2 ) % M) % M;
}

int main()
{
cin
>> A >> B;
int i;
// 将A分解成唯一p1^a1*p2^a2*...pi^ai...*pn^an
// p[i]记录pi,c[i]记录ai
for ( i = 2 ;i * i <= A;i ++ )
{
if (A % i == 0 )
{
p[
++ count] = i;
while (A % i == 0 )
{
A
/= i;
c[count]
++ ;
}
}
}
if (A != 1 )
{
p[
++ count] = A;
c[count]
= 1 ;
}
// 公式:(A*B)%C=((A%C)*(B%C))%C
__int64 res = 1 ;
for (i = 1 ;i <= count;i ++ )
res
= (res % M * Sum(p[i],B * c[i]) % M);
// __int64无法用cout输出
printf( " %d\n " ,res);
return 0 ;
}

 

你可能感兴趣的:(div)