I was searching some problems that would require modular inverse / Chinese remainder theorem / Extended Euclidean algorithm. This problem requires the simplest case of modular inverse when the numbers in question are co-prime.
The problem in short
Find the sum of divisors of the number 2004^X mod 29 [1<=X<=10000000].So, first we need to find the sum of divisors of an arbitrary number N. Let prime factorization of N is -
N = (p1^a1) * (p2^a2) * ...... * (pn^an)Then the sum of its divisors would be -
S = (1 + p1 + ... + p1^a1) * (1 + p2 + ... + p2^a2) * ...... * (1 + pn + ... + pn^an)= (p1^(a1+1) - 1) / (p1 - 1) * (p2^(a2+1) - 1) / (p2 - 1) * ...... * (pn^(an+1) - 1) / (pn - 1)
You need to calculate S mod 29. The problem is all the terms in S are of the form (x/y). To calculate (x/y) mod m, we need to find a z such that -
(1/y) congruent to z (mod m)If y and m are co-prime, then it is very easy to find. Modular inverse z would be
z = y ^ (phi(m) - 1) mod mAs m is a prime number in this problem, it will be co-prime with the prime factors of 2004 (which are 2,3 and 167) and phi(m) = m -1.
Combining all these equations, we can easily solve the problem.
Source code below -
/*
Problem Name : MMOD29
Problem Number : SPOJ 3909
Link : http://www.spoj.pl/problems/MMOD29/en/
Problem Type : Math
Difficulty : 4.5 / 10
Interest : 6 / 10
Complexity : O(lgX)
Date : December 2, 2010
*/
#include <stdio.h>
#define rep(i,n) for(i=0;i<(n);i++)
int bigmod(int b, int p, int m) {
if(p == 0) return 1;
if(p == 1) return b%m;
if(p&1) return ((b%m) * bigmod(b,p-1,m)) % m;
else {
int sq = bigmod(b,p/2,m);
return (sq * sq) % m;
}
}
int main() {
int n,res,i,x;
int primes[] = {2,3,167};
int powers[] = {2,1,1};
int MOD = 29;
while(scanf(" %d",&n) == 1) {
if(n == 0) break;
res = 1;
rep(i,3) {
x = (bigmod(primes[i],powers[i]*n+1,MOD) - 1 + MOD) % MOD;
res = (res * x) % MOD;
x = bigmod(primes[i]-1,MOD-2,MOD);
res = (res * x) % MOD;
}
printf("%d\n",res);
}
return 0;
}
No comments:
Post a Comment