### 计数原理
$C^n_m=A^n_m/m!$=n!/(m!)*(n-m)!
[卢卡斯定理](https://baike.baidu.com/item/lucas/4326261)
### 乘法逆元
若a与x在模p意义下互为乘法逆元。记为a=inv[x],a的-1次方=x;
若出现 (a/b)%p,不能等价于 (a%p)/(b%p),可以用a乘b的逆元inv[b], a* inv[b]%p;
求单个整数的逆元
1:拓展欧几里得 ax+py=1
2:有限情况下使用费马小定理
注:
乘法逆元不一定存在
乘法逆元若存在,那么有无数个但在模p意义下只有一个
##### 费马小定理
若p是质数,且gcd(a,p)==1,a的p-1次方在模p意义下与1同余。
a的乘法逆元=a的p-2次方(%p)(若乘法逆元存在)
------------
求1到n的所有整数的逆元(若存在)
a*x与1关于模p意义下同余
设 p=a*q+r, 其中 q=p/a , r=p%a
则p=a*q+r在模p意义下与0同余
两边同-r,再同乘q的逆元
a在模p意义下与-r*inv[q]同余
(两边同取逆元)
inv[a]=-q*inv[p%a](mod p);
inv[a]=-p/a*inv[p%a] (mod p)
dp求前n个数的逆元(存在)
inv[1]=1
for(int i=2;i<=n;i++){
inv[i]=(p-p/i)*inv[p%i]%p;
}
------------
欧拉函数
欧拉函数:定义φ(n) 表示不超过n的数中与n互质的正整数的个数
φ(1) =1
欧拉函数的常用性质:
1.若p是质数,则φ($p^n$)= $p^{n-1}$(p-1)
2.若a|x,则φ(ax)=a*φ(x)
3.若a,b互质,则φ(a)*φ(b)=φ(ab)
求欧拉函数
1. 求单个数的欧拉函数 O(log(n))
```cpp
#include<bits/stdc++.h>
using namespace std;
int phi(int n){
int res=n;
for(int i=2;i*i<=n;i++){
if(n%i==0)
res=res/i*(i-1);
while(n%i==0)
n/=i;
}
if(n>1) res=res/n*(n-1);
return res;
}
int main(){
cout<<phi(114514);
return 0;
}
```
2.用线性筛求1-n以内的所有数的欧拉函数 O(n)
#include<bits/stdc++.h>
using namespace std;
bool vis[114514];
int cnt,q[114514],phi[114514];
void o(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
q[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt;j++){
if(q[j]*i>n)
break;
vis[q[j]*i]=1;
if(i%q[j]==0){
phi[q[j]*i]=phi[i]*q[j];
break;
}else{
phi[q[j]*i]=(q[j]-1)*phi[i];
}
}
}
}
int main(){
o(20);
for(int i=1;i<=20;i++){
cout<<phi[i]<<' ';
}
return 0;
}
------------
欧拉定理
设a,m是正整数,且gcd(a,m)=1,那么$a^{φ(m)}$=1(mod m)
拓展欧拉定理
若b>=φ(m),则a^b=a^{b\mod\varphi m+\varphi m} (mod m)
当gcd(a,m)=1,a^b=a^{b\mod\varphi m} (mod m)