Quick stuff first, fast exponentiation in logarithm time.
Let us calculate
It uses binary expansion of
ll exp(ll x, ll n) { if(n==0) return 1; if(n==1) return x; if(n%2==0) return exp((x*x)%mod,n/2); if(n%2==1) return (x*exp((x*x)%mod,n/2))%mod; }
Now, let us talk about modular inverses.
By using Extended Euclidean Algorithm, we can get the inverse of
#include <iostream> int inv(int a, int m) { int temp=m, q, t, u=0, v=1; if(m==1) return 0; while(a>1) { q=a/m; t=m; m=a%m; a=t; t=u; u=v-q*u; v=t; } if(v<0) v+=temp; return v; } int main(void) { int a, m; std::cin>>a>>m; std::cout<<inv(a,m); }
Of course, logarithm time. If
Fermat's Little Theorem gives
Therefore, we can calculate the modular inverse of
Time Complexity is
Also, you can get the modular inverse of all numbers in
The code for this is shown below. The proof for the correctness is left to the reader (not difficult)
#include <iostream> typedef long long ll; using namespace std; int inv[111111], n; ll mod=1e9+7; int main(void) { cin>>n; int i; inv[1]=1; for(i=2 ; i<=n ; i++) { inv[i]=((mod-mod/i)*inv[mod%i])%mod; cout<<inv[i]<<endl; } }
We can also calculate
Lucas' Theorem basically states that
, where This is very efficient when
Also, we can use Chinese Remainder Theorem to solve a system of modular equations.
Let us solve
(If they are not coprime, break them into prime powers, and if some are contradictory, there are no solutions.)
The CRT itself gives an algorithm to get our answer.
Set
We learned how to calculate modular inverse in logarithm time above. So the time complexity is
long long int r[111111]; // remainders long long int m[111111]; // modulars long long int M=1; // product int n; // number of equation int res(void) { int i; for(i=1 ; i<=n ; i++) { M=M*m[i]; } long long int ret=0; for(i=1 ; i<=n ; i++) { ret+=r[i]*inv(M/m[i],m[i])*(M/m[i]); ret=ret%M; } return ret; }
Formula is
Also, we have the formula
Of course, for the calculation of Euler Phi numbers, we can tweak the Eratosthenes's Sieve algorithm a little bit.
void preprocess(void) { int i, j; eulerphi[1]=1; for(i=2 ; i<=122000 ; i++) { eulerphi[i]=i; primechk[i]=1; } for(i=2 ; i<=122000 ; i++) { if(primechk[i]==1) { eulerphi[i]-=eulerphi[i]/i; for(j=2 ; i*j<=122000 ; j++) { primechk[i*j]=0; eulerphi[i*j]-=eulerphi[i*j]/i; } } } }
You could also calculate
Now let's get to the fun stuff. The mobius function.
Comments
Post a Comment