Happy 2004
问题描述 :
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.
输入:
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.
输出:
For each test case, in a separate line, please output the result of S modulo 29.
样例输入:
1 10000 0
样例输出:
6 10
设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
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #include <map> 8 #include <set> 9 using namespace std; 10 #define LL long long 11 const int INF=0x3f3f3f3f; 12 const double eps=1e-5; 13 int p=29; 14 LL pow_mod(LL x,LL n) 15 { 16 LL res=1; 17 while(n>0) 18 { 19 if(n&1) res=res*x%p; 20 x=x*x%p; 21 n>>=1; 22 } 23 return res; 24 } 25 int main() 26 { 27 LL x,i; 28 while(cin>>x&&x) 29 { 30 int a=pow_mod(2,2*x+1); 31 int b=pow_mod(3,x+1); 32 int c=pow_mod(22,x+1); 33 int s=((a-1)*(b-1)*(c-1)*15*18)%29; 34 cout<<s<<endl; 35 } 36 37 }