素数:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int p[10000000],a[100000001];
int main()
{
int i,t=0,j,n;
scanf("%d",&n);
a[1]=1;
for (i=2;i<=n;++i)
{
if (!a[i])
p[++t]=i;
for (j=1;j<=t&&i*p[j]<=n&&(a[i*p[j]]==0||a[i*p[j]]>p[j]);++j)
{
a[i*p[j]]=p[j];
if (!i%p[j]) break;
}
}
}
快速幂:
int pow(int x,int a,int p)
{
int t;
if (a==0) return 1%p;
if (a==1) return x%p;
t=pow(x,a/2,p);
if (a%2) return ((t*t)%p*x)%p;
else return (t*t)%p;
}
欧拉函数:
欧拉函数 ϕ(n) 是指1~n-1内与n互质的数的个数,通常用公式
ϕ(n)=n∗(1−1p1)∗(1−1p2)∗...∗(1−1pk)
m=floor(sqrt(n));
phi[n]=n;
for (int i=2;i<=m;++i)
if (n%i==0)
{
phi[n]=phi[n]/i*(i-1);
while (n%i==0) n/=i;
}
if (n>1) phi[n]=phi[n]/n*(n-1);
int phi[maxn];
void phin(int n)
{
for (int i=2;i<=n;++i) phi[i]=0;
phi[1]=1;
for (int i=2;i<=n;++i) if (!phi[i])
for (int j=i;j<=n;j+=i) {
if (phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
欧拉定理:
设 gcd(x,p)=1 (若 x<p ,则称 x 为
xϕ(p)=1(modp)
特别地 当p为质数时 ϕ(p)=p−1 则有
xp−1=1mod(p)
最小公倍数类:
gcd(a,b)∗lcm(a,b)=a∗b
欧几里德算法(运算次数最多为fib[n]与fib[n-1],辗转相除):
int gcd(int a,int b)
{
if (a%b==0) return b;
else return gcd(b,a%b);
}
高精度(Stein 算法):
gcd(x,y)=gcd(x,y/2)(x−>odd,y−>even)
gcd(x,y)=2∗gcd(x/2,y/2)(x,y−>even)
gcd(x,y)=gcd(x,y−x)(x,y−>odd)
拓展欧几里德算法,用于求 ax+by=gcd(a,b)) 的最小解( |x|+|y| 最小):
void exgcd(int a,int b,int &d,int &x,int &y)
{
if (b==0)
{
d=a;
x=1;
y=0;
}
else
{
exgcd(b,a%b,d,y,x);
y-=(a/b)*x;
}
}
同余类:
线性同余方程:
ax=b(modp) = >ax−py=b =>若 gcd(a,p)|b 则有扩展欧几里德算法 x=x∗b/(gcd(a,p))
特别地当 b=1 且 gcd(a,p)=1 时, a 与
求逆元:
基于扩展欧几里德: