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
![$[1,n]$](https://latex.artofproblemsolving.com/2/2/4/2240bb122bdadbe086c0a6291dcd5a3eb82ad5cf.png)

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







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