Reputation: 1445
I wrote the following program in python for the following codechef question http://www.codechef.com/problems/MOVES/
import sys
tokenizedInput = sys.stdin.read().split()
mod=1000000007
arr=[1]*5001
for i in range(1,5001):
arr[i]=(arr[i-1]*i)%mod
def combo(r,n,mod):
q=arr[n]
print q
r=(arr[r]*arr[n-r])
print r
return ((q/r)%mod)
elm=0
for i in range (0,5001):
n=int(tokenizedInput[elm])
elm=elm+1
k=int(tokenizedInput[elm])
elm=elm+1
if(n==0 and k==0):
break
out=0
if(((k-1)/2)!=(k/2)):
out=(2*combo((k-1)/2,n-2,mod)*combo(k/2,n-2,mod))%mod
else:
out=(2*combo(k/2,n-2,mod)**2)%mod
print out
but my modulo function is not working correctly for example for values n=498 and r=2 the answer returned by combo() is 0 because q=243293343 and r=1428355228 how to perform my modulo operation in arr[] to rectify this error ?
Upvotes: 3
Views: 731
Reputation: 75
The above power function calculates a^b in O( log(b) ) by using what is called as exponentiation by squaring. The idea is very simple:
(a^2)^(b/2) if b is even and b > 0
a^b = a*(a^2)^((b-1)/2) if b is odd
1 if b = 0
This idea can be implemented very easily as shown below:
/* This function calculates (a^b)%c */
int modulo(int a,int b,int c)
{
long long x=1,y=a;
while(b > 0)
{
if(b%2 == 1)
{
x=(x*y)%c;
}
y = (y*y)%c; // squaring the base
b /= 2;
}
return x%c;
}
The above power function is just a recursive way of doing this. and as you asked about this
but it will be of great help if anyone explains the mathematics behind using return(base*Power(base,expo-1)%mod)
this is the same as checking if expo is odd then multiplying base with base^(expo-1) so that the new expo i.e. (expo-1) will become even and repeated squaring can be done
For more info refer:
Upvotes: 1
Reputation: 786
When we divider (a/b)%MOD , then we do something like this .
(a/b)%MOD
(a*inverse(b))%MOD // You have to find the inverse of b. To find the inverse of b use Fermat Theorem.
Note never divide a/b and then take MOD , first find the inverse of b and then do a*b and then MOD it .
Upvotes: 0
Reputation: 1445
Got the solution,Answering my own question , but search for an optimized version is encouraged the error was
return ((q/r)%mod)
is wrong for mod being 1000000007 ie a prime number , it has to be written as
r=(arr[r]*arr[n-r])%mod
return (q*Power(r,mod-2))%mod
where Power function is
def Power(base,expo):
if(expo==0):
return 1
else:
if(expo&1):
return(base*Power(base,expo-1)%mod)
else:
root=Power(base,expo>>1)
return(root*root%mod)
but it will be of great help if anyone explains the mathematics behind using return(base*Power(base,expo-1)%mod)
Upvotes: 0