逆元
1.扩展gcd求逆元
void ex_gcd(LL a , LL b , LL& d , LL &x , LL &y) {
if (b == 0 ) {
x = 1 , y = 0 ;
d = a ;
return ;
}
ex_gcd(b , a%b , d , y , x) ;
y -= x*( a/b) ;
}
LL inv(LL a , LL n) {
LL d , x , y ;
ex_gcd(a , n , d , x , y) ;
return d == 1 ? (x+n)%n : -1 ;
}
2.递推求逆元
int inv[N];
void get_inv(int n, int p) {
inv[1 ] = 1 ;
for (int i = 2 ; i <= n; ++i) {
inv[i] = (p - p / i) * inv[p % i] % p;
}
}
素数筛法
bool isp[N] ; int prime[N] ; int np ;
void getPrime() {
memset (isp , true , sizeof (isp)) ;
np = 0 ;
for (int i = 2 ; i < N ; ++i) {
if (isp[i]) prime[np++] = i ;
for (int j = 0 ; j < np ; ++j) {
if (prime[j]*i >= N) break ;
isp[prime[j]*i] = false ;
if (i%prime[j] == 0 ) break ;
}
}
}
欧拉函数
int phi[N] ;
void getPhi() {
memset (phi , 0 , sizeof (phi)) ;
phi[1 ] = 1 ;
for (int i = 2 ; i < N ; ++i) {
if (phi[i] == 0 ) {
for (int j = i ; j < N ; j += i) {
if (phi[j] == 0 ) phi[j] = j ;
phi[j] = phi[j]/i*(i-1 ) ;
}
}
}
}
莫比乌斯函数
int mu[N] ;
int prime[N] ; bool isp[N] ; int np ;
void getMu() {
memset (isp , true , sizeof (isp)) ;
mu[1 ] = 1 ; np = 0 ;
for (int i = 2 ; i < N ; ++i) {
if (isp[i]) {
prime[np++] = i ;
mu[i] = -1 ;
}
for (int j = 0 ; j < np ; ++j) {
if (i*prime[j] >= N) break ;
isp[i*prime[j]] = false ;
if (i%prime[j]) mu[i*prime[j]] = -mu[i] ;
else {
mu[i*prime[j]] = 0 ;
break ;
}
}
}
}
组合数取模
1.预处理,求C(n , k)%Mod n <= 1e6
const int N = 2 e5 + 11 ;
const int Mod = 1 e9 + 7 ;
LL inv[N] ;// 递推求x 的逆元
LL fac[N] ;// 阶乘
LL rfc[N] ;// 递推求x !的逆元
void init() {
inv[0 ] = inv[1 ] = 1 ;
fac[0 ] = fac[1 ] = 1 ;
rfc[0 ] = rfc[1 ] = 1 ;
for (int i = 2 ; i < N ; ++i) {
inv[i] = ((Mod- Mod/i)*inv [Mod%i ])%Mod ;
fac[i] = (fac[i-1 ]*i )%Mod ;
rfc[i] = (rfc[i-1 ]*inv [i])%Mod ;
}
}
LL com(LL n , LL k){
return (fac[n]*rfc [k]%Mod )*rfc [n-k]%Mod ;
}