Happy 2004
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1393 Accepted Submission(s): 1018
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
n的因子和为s(n)
令g(p, e) = (p^(e+1) - 1) / (p-1),则s(n) = g(p1, e1) * g(p2, e2) * ... * g(pk, ek)
这个题只不过是求nx的因子和而已,假设 n = p1e1p2e2...pnen 那么 nx=p1e1*xp2e2*x...pnen*x 由于这题x的范围比较大,所以要用快速取模,又因为这题有除法取模,而模的数又是一个质数,所以要用到逆元.
#include <stdio.h> #include <algorithm> #include <string.h> #include <math.h> #include <queue> using namespace std; typedef long long LL; const int N = 10000005; LL p[3]={2,3,167}; LL e[3]={2,1,1}; LL extend_gcd(LL a,LL b,LL &x,LL &y){ if( b == 0 ) { x = 1; y = 0; return a; } else{ LL x1,y1; LL d = extend_gcd(b,a%b,x1,y1); x = y1; y= x1-a/b*y1; return d; } } LL mod_reverse(LL a,LL n) { LL x,y; LL d=extend_gcd(a,n,x,y); if(d==1) return (x%n+n)%n; else return -1; } LL pow_mod(LL a,LL n,LL mod){ LL ans = 1; while(n){ if(n&1) ans = ans*a%mod; a= a*a%mod; n=n>>1; } return ans; } LL g(LL p,LL e){ LL inv = mod_reverse(p-1,29); LL ans = (inv*(pow_mod(p,e+1,29)-1))%29; return ans; } int main() { LL n; while(scanf("%lld",&n)!=EOF,n){ LL m = 2004; LL sum = 1; for(int i=0;i<3;i++){ sum = (sum*g(p[i],e[i]*n))%29; } printf("%lld ",sum); } return 0; }