HDU 1452 Happy 2004

设S(x)表示x的因子和。则题目求为:S(2004^X)mod 29
因子和S是积性函数,即满足性质1。

性质1 :如果 gcd(a,b)=1  则 S(a*b)= S(a)*S(b)
2004^X=4^X * 3^X *167^X
S(2004^X)=S(2^(2X)) * S(3^X) * S(167^X)

性质2 :如果 p 是素数 则 S(p^X)=1+p+p^2+...+p^X = (p^(X+1)-1)/(p-1)
因此:S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (167^(X+1)-1)/166
167%29 == 22
S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/21

性质3 :(a*b)/c %M= a%M * b%M * inv(c)
其中inv(c)即满足 (c*inv(c))%M=1的最小整数,这里M=29
则inv(1)=1,inv(2)=15,inv(22)=15

有上得:
S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/21
=(2^(2X+1)-1) * (3^(X+1)-1)*15 * (22^(X+1)-1)*18

 AC code:

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 
 5 using namespace std;
 6 
 7 int _pow( int a, int n )
 8 {
 9     int b = 1;
10     while( n > 1 )
11         if( n % 2 == 0 )
12         {
13             a = ( a * a ) % 29;
14             n /= 2;
15         }
16         else
17         {
18             b = b * a % 29;
19             n--;
20         }
21         return a * b % 29;
22 }
23 int main()
24 {
25     int X;
26     int a, b, c;
27     while( cin >> X, X )
28     {
29         a = _pow( 2, 2 * X + 1 );
30         b = _pow( 3, ( X + 1 ) );
31         c = _pow( 22, ( X + 1 ) );
32 
33         cout << ( a - 1 ) * ( b - 1 ) * 15 * ( c - 1 ) * 18 % 29 << endl;
34     }
35     return 0;
36 }
posted @ 2012-04-24 17:44  背着超人飞  阅读(327)  评论(0)    收藏  举报