hdu 1452 Happy 2004 膜拜这推导过程
Happy 2004
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 920 Accepted Submission(s): 648
Problem Description
Consider a positive integer X,and let S be the sum of all positive integer divisors of 2004^X. Your job is to determine S modulo 29 (the rest of the division of S by 29).
Take X = 1 for an example. The positive integer divisors of 2004^1 are 1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 and 2004. Therefore S = 4704 and S modulo 29 is equal to 6.
Take X = 1 for an example. The positive integer divisors of 2004^1 are 1, 2, 3, 4, 6, 12, 167, 334, 501, 668, 1002 and 2004. Therefore S = 4704 and S modulo 29 is equal to 6.
Input
The input consists of several test cases. Each test case contains a line with the integer X (1 <= X <= 10000000).
A test case of X = 0 indicates the end of input, and should not be processed.
A test case of X = 0 indicates the end of input, and should not be processed.
Output
For each test case, in a separate line, please output the result of S modulo 29.
Sample Input
1
10000
0
Sample Output
6
10
Source
1 /* 2 性质1 : 3 如果 gcd(a,b)=1 则 S(a*b)= S(a)*S(b) 4 2004^X=4^X * 3^X *167^X 5 S(2004^X)=S(2^(2X)) * S(3^X) * S(167^X) 6 性质2 :如果 p 是素数 则 S(p^X)=1+p+p^2+...+p^X = (p^(X+1)-1)/(p-1) 7 (2^(2X+1)-1) * (3^(X+1)-1)/2 * (167^(X+1)-1)/166 8 167%29 = 22 9 S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/166 10 性质3 :(a*b)/c %M= a%M * b%M * inv(c) 11 其中inv(c)即满足 (c*inv(c))%M=1的最小整数,这里M=29 12 则inv(1)=1,inv(2)=15,inv(21)=18 13 有上得: 14 S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/21 15 =(2^(2X+1)-1) * (3^(X+1)-1)*15 * (22^(X+1)-1)*18 16 */ 17 18 #include<iostream> 19 #include<stdio.h> 20 #include<cstring> 21 #include<cstdlib> 22 using namespace std; 23 typedef __int64 LL; 24 25 const LL p = 29; 26 27 LL pow_mod(LL a,LL n) 28 { 29 LL ans=1; 30 while(n) 31 { 32 if(n&1) ans=(ans*a)%p; 33 n=n>>1; 34 a=(a*a)%p; 35 } 36 ans=ans-1; 37 if(ans<0) ans=ans+p; 38 return ans; 39 } 40 void solve(LL x) 41 { 42 LL sum=1; 43 sum=(sum*pow_mod(3,x+1)*15)%p; 44 sum=(sum*pow_mod(2,2*x+1))%p; 45 sum=(sum*pow_mod(22,x+1)*18)%p; 46 printf("%I64d\n",sum); 47 } 48 int main() 49 { 50 LL x; 51 while(scanf("%I64d",&x)>0) 52 { 53 if(x==0)break; 54 solve(x); 55 } 56 return 0; 57 }