// Extended Euclidean algorithm.voidex_gcd(inta,intb,int&x,int&y){if(!b){x=1;y=0;}else{ex_gcd(b,a%b,y,x);y-=a/b*x;}}// Returns the modular inverse of a modulo m.// Assumes that gcd(a, m) = 1, so the inverse exists.intinverse(inta,intm){intx,y;ex_gcd(a,m,x,y);return(x%m+m)%m;}
1 2 3 4 5 6 7 8 910111213141516
# Extended Euclidean algorithm.defex_gcd(a,b):ifb==0:return1,0else:x1,y1=ex_gcd(b,a%b)x=y1y=x1-(a//b)*y1returnx,y# Returns the modular inverse of a modulo m.# Assumes that gcd(a, m) = 1, so the inverse exists.definverse(a,m):x,y=ex_gcd(a,m)return(x%m+m)%m
// Binary exponentiation.intpow(inta,intb,intm){longlongres=1,po=a;for(;b;b>>=1){if(b&1)res=res*po%m;po=po*po%m;}returnres;}// Returns the modular inverse of a prime modulo p.intinverse(inta,intp){returnpow(a,p-2,p);}
1234
# Returns the modular inverse of a prime modulo p.# Use built-in pow function.definverse(a,p):returnpow(a,p-2,p)
// Returns the modular inverses for each x in a modulo m.// Assume x mod m exists for each x in a.std::vector<int>batch_inverse(conststd::vector<int>&a,intm){intn=a.size();std::vector<int>prod(n);longlongs=1;for(inti=0;i<n;++i){prod[i]=s;s=s*a[i]%m;}s=inverse(s,m);std::vector<int>res(n);for(inti=n-1;i>=0;--i){res[i]=s*prod[i]%m;s=s*a[i]%m;}returnres;}
1 2 3 4 5 6 7 8 9101112131415
# Returns the modular inverses for each x in a modulo m.# Assume x mod m exists for each x in a.defbatch_inverse(a,m):n=len(a)prod=[0]*ns=1foriinrange(n):prod[i]=ss=s*a[i]%ms=inverse(s,m)res=[0]*nforiinreversed(range(n)):res[i]=s*prod[i]%ms=s*a[i]%mreturnres
// Precomputes modular inverses of all integers from 1 to n modulo prime p.std::vector<int>precompute_inverses(intn,intp){std::vector<int>res(n+1);res[1]=1;for(inti=2;i<=n;++i){res[i]=(longlong)(p-p/i)*res[p%i]%p;}returnres;}
1234567
# Precomputes modular inverses of all integers from 1 to n modulo prime p.defprecompute_inverses(n,p):res=[0]*(n+1)res[1]=1foriinrange(2,n+1):res[i]=(p-p//i)*res[p%i]%preturnres