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.
 

 

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.
 

 

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 }

 

posted @ 2014-05-12 23:12  芷水  阅读(145)  评论(0编辑  收藏  举报