没有证明,实际的证明在做题的时候也没多大用,(证明看一遍忘一遍)别记错模版和复杂度就行。
\(\\\)
\(\\\)
\(\\\)
对于一个正整数\(N\),不超过它的质数有\(\frac{N}{lnN}\)个。
\(\\\)
试除法\(O(\sqrt n)\)
结论:若一个正整数\(N\)为合数,那么一定存在一个能够整除\(N\)的正整数\(T\),使得\(2\le T\le \sqrt n\)。
bool is_prime(int n){
if(n<2) return false;
for(int i=2;i<=sqrt(n);i++)
if(n%i==0) return false;
return true;
}
\(\\\)
质数的筛选埃式筛法\(O(NloglogN)\)
结论:任意整数\(x\)的倍数\(2x,3x,…\)都不是质数。
void primes(int n){
for(int i=2;i<=n;i++){
if(v[i]) continue;
prime[++cnt]=i;//不是2~i-1任何一个数的倍数
for(int j=i;j<=n/i;j++){//从i的i倍开始,小于i倍的已经被标记过了
v[i*j]=true;
}
}
}
线性筛法\(O(N)\)
记录mindiv,让每个数只被它的最小质因数筛一次。
void primes(int n){
memset(mindiv,0,sizeof(mindiv));
cnt=0;
for(int i=2;i<=n;i++){
if(mindiv[i]==0){
mindiv[i]=i;
prime[++cnt]=i;
}
for(int j=1;j<=cnt;j++){
if(prime[j]>mindiv[i]||i*prime[j]>n) break;
mindiv[i*prime[j]]=prime[j];
}
}
}
\(\\\)
质因数分解算数基本定理(唯一分解定理)
任何一个大于\(1\)的正整数都能唯一分解为有限个质数的乘积。即:
\(N=p_1^{c_1}p_2^{c_2}p_3^{c_3}…p_m^{c_m}\)
试除法\(O(\sqrt n)\)
做法:扫描\(2\)~\(\sqrt n\)里的每个数\(d\),若\(d|n\),那么删掉\(n\)中的所有因子\(d\),并累计个数。
正确性:一个合数的因子一定在扫到合数之前就被删除了,所以能整除\(n\)的一定是小于n的质数。
void divide(int n){
cnt=0;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
p[++cnt]=i;
while(n%i==0) n/=i,c[cnt]++;
}
}
if(n>1){
p[++cnt]=n;
c[cnt]=1;
}
}
\(\\\)
\(\\\)
\(\\\)
唯一分解定理的推论
\(n\)的正约数个数为:\((c_1+1)\times (c_2+1)\times …\times(c_m+1)\)
\(n\)的正约数和为:\((1+p_1+{p_1}^2+…+p_1^{c_1})\times …\times (1+p_m+{p_m}^2+…+{p_m}^{c_m})\)
\(\\\)
求\(n\)的正约数集合—试除法\(O(\sqrt n)\)
结论:若\(d\)是\(n\)的约数,那么\(n/d\)也是\(n\)的约数。
推论:一个整数\(n\)的约数个数上界是\(2\sqrt n\)
void get_factor(int n){
for(int i=1;i<=sqrt(n);i++){
if(n%i==0){
factor[++cnt]=i;
if(i!=n/i) factor[++cnt]=n/i;
}
}
}
求\(1\)~\(n\)的正约数集合—倍数法
推论:\(1\)~\(n\)的约数个数上届是\(nlogn\)
void get_factor(int n){
for(int i=1;i<=n;i++){
for(int j=1;j<=n/i;j++)
factor[i*j].push_back(i);
}
}
\(\\\)
最大公约数与最小公倍数结论:\(\text{lcm}(a,b)=\frac{a\times b}{\text{gcd}(a,b)}\)
欧几里得算法\(O(log\ {a+b})\)
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
\(\\\)
\(\\\)
\(\\\)
- \(\forall n>1,1\)~\(n\)中与\(n\)互质的数的和为\(\frac{n\times \varphi(n)}{2}\)。
- 若\(a,b\)互质,则\(\varphi(a\times b)=\varphi(a)\times \varphi(b)\)。
- 设\(p\)为质数,\(p|n\)且\(p^2|n\),则\(\varphi(n)=\varphi(n/p)\times p\)。
- 设\(p\)为质数,\(p|n\)且\(p^2\nmid n\),则\(\varphi(n)=\varphi(n/p)\times p\)。
-
\(\sum_{d|n}\varphi(d)=n\)
\(\\\)
求解\(n\)的欧拉函数\(O(\sqrt n)\)
结论:在算数基本定理中,\(N={p_1}^{c_1}{p_2}^{c_2}…{p_m}^{c_m}\),那么\(\varphi(N)=N*\frac{p_1-1}{p_1}*\frac{p_2-1}{p-2}*…*\frac{p_m-1}{p_m}\)。
int phi(int n){
int ans=n;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0) ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
求解\(1\)~\(n\)的欧拉函数
埃式筛法\(O(nlogn)\)
void euler(int n){
for(int i=2;i<=n;i++) phi[i]=i;
for(int i=2;i<=n;i++){
if(phi[i]==i){
for(int j=i;j<=n;j+=i)
phi[i*j]=phi[j]/i*(i-1);
}
}
}
线性筛法\(O(n)\)
void euler(int n){
memset(mindiv,0,sizeof(mindiv));
cnt=0;
for(int i=2;i<=n;i++){
if(mindiv[i]==0){
mindiv[i]=i;prime[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt;j++){
if((prime[j]>mindiv[i])||(prime[j]>n/i)) break;
mindiv[i*prime[j]]=prime[j];
phi[i*prime[j]]=phi[i]*(i%prime[j]?(prime[j]-1):prime[j]);
}
}
}
\(\\\)
\(\\\)
\(\\\)
费马小定理
若\(p\)是质数,则对于任意整数\(a\),有\(a^p\equiv a (\text{mod} \ p)\)
\(\\\)
欧拉定理
若\(gcd(a,n)=1\),那么\(a^{\varphi(n)}\equiv 1(\text{mod} \ n)\)
\(\\\)
扩展欧拉定理
\(\\\)
裴蜀定理
对于任意整数\(a,b\),存在一对整数\(x,y\),使得\(ax+by=\text{gcd}(a,b)\)
我的理解是,如果存在一个数\(c\),使得\(ax+by=c\)成立,那么\(c\)一定能整除\(\text{gcd}(a,b)\)
\(\\\)
扩展欧几里得算法\(O(log\ {a+b})\)
用来求\(ax+by=\text{gcd}(a,b)\)的一组可行解\(x_0\),\(y_0\)。
void exgcd(int a,int b,int &x,int &y){
if(b==0) {x=1;y=0;return a;}
int gcd=exgcd(b,a%b,x,y);
int tmp=x;x=y;y=tmp-(a/b)*y;
return gcd
}
对于一般方程\(ax+by=c\)。
- 有解条件:\(gcd\mid c\)
- 可行解:\(x=\frac{c}{gcd}x_0\),\(y=\frac{c}{gcd}y_0\)
- 通解:\(x=\frac{c}{gcd}x_0+k\frac{b}{gcd}\),\(y=\frac{c}{gcd}y_0-k\frac{a}{gcd}(k\epsilon\mathbb{Z} )\)
\(\\\)
\(\\\)
\(\\\)
求解\(a\)在模\(n\)意义下的逆元\(a^{-1}\)
快速幂法\(O(log_2n)\)
适用条件:\(n\)为质数
int qpow(int a,int b,int n){
int res=1;
while(b){
if(b&1) res=res*a%n;
a=a*a%n;
b>>=1;
}
return res;
}
qpow(a,n-2,n);
扩展欧几里得法\(O(log_2{a+n})\)
转化为\(a*x\equiv1(\text{mod}\ n)\Rightarrow\ a*x+n*y=1\),求出一组特解\(x_0,y_0\),\(x_0\)就是一个\(a\)在模\(n\)意义下的逆元。
适用条件:\(gcd(a,n)=1\)
通解:\(x\equiv x_0(\text{mod} n)\)
最小整数解:\((x_0+n)\%n\)
void exgcd(int a,int b,int &x,int &y){
if(b==0) {x=1;y=0;return a;}
int gcd=exgcd(b,a%b,x,y);
int tmp=x;x=y;y=tmp-(a/b)*y;
return gcd
}
exgcd(a,n,x,y)
求解\(1\)~\(n\)中,每个数在模\(p\)意义下的逆元\(O(n+log(p))\)
适用条件:\(p\)为质数
void getinv(){
s[0]=1;
for(int i=1;i<=n;i++) s[i]=s[i-1]*a[i]%p;
sv[n]=qpow(s[n],p-2,p);
for(int i=n;i>=1;i--) sv[i-1]=sv[i]*a[i]%p;
for(int i=1;i<=n;i++) inv[i]=sv[i]*s[i-1]%p;
}
\(\\\)
\(\\\)
\(\\\)
求解同余方程
给定整数\(a,b,m\),求解一个整数\(x\)满足\(a*x\equiv b(\text{mod}\ m)\),或者判定无解
\(a*x\equiv b(\text{mod}\ m)\Rightarrow a*x+m*y=b\)
判定有解:\(\text{gcd}(a,m)|b\)。
通解:\(x_0*\frac{b}{\text{gcd}(a,m)}+k*\frac{m}{\text{gcd}(a,m)}\)
\(\\\)
中国剩余定理
对于如下的方程组
\(\begin{cases} x\equiv a_1\ (\text{mod}\ m_1)\\ x\equiv a_2\ (\text{mod}\ m_2)\\ \vdots \\ x\equiv a_n\ (\text{mod}\ m_n)\\ \end{cases}\)
求解\(x\),其中\(m\)两两互质。
记\(m=\prod_{i=1}^n m_i\),\(M_i=\frac{m}{m_i}\),\(t_i\)是同余方程\(M_it_i\equiv1(\text{mod}\ m_i)\)的一个解。
可行解:\(x_0=\sum_{i=1}^{n}a_iM_it_i\)。
通解:\(x=x_0+km\)
最小正整数解:\(x=(x_0+m)\%m\)
int crt(int k,int *a,int *b){
int m=1,ans=0;
for(int i=1;i<=k;i++) m=m*b[i];
for(int i=1;i<=k;i++){
int M=m/b[i],t,y;
exgcd(M,b[i],t,y);
ans=((ans+a[i]*M*t%m)+m)%m;
}
return (ans+m)%m;
}
\(\\\)
威尔逊定理(www)
我刚知道考纲里还有这个????