求素数的个数
void su()
{
vector<bool >vis(n+1,0);
vector<int >prime(5761456,0);//最多这么多5761455
for(int i=2;i<=n;++i)
{
if(!vis[i])
{
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=n;++j)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
同余方程
#include<bits/stdc++.h>
#define intn long long
#define _0for(i, a) for(int i = 0; i < (a); ++i)
#define _1for(i, a) for(int i = 1; i <=(a); ++i)
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
if(a<b)return exgcd(b,a,y,x);
if(b==0)
{
x=1;y=0;
return a;
}
else
{
int x1;
int d=exgcd(b,a%b,x1,x);
y=x1-a/b*x;
return d;
}
}
main(void)
{
int a,b;
cin>>a>>b;
int x=0,y=0;
int p=exgcd(a,b,x,y);
while(x<=0)
{
x+=b;
}
cout<<x/p<<endl;
}
乘法逆元

法一、扩欧
法二、费马小定理


//递归快速幂
int qpow(int a, int n)
{
if (n == 0)
return 1;
else if (n % 2 == 1)
return qpow(a, n - 1) * a;
else
{
int temp = qpow(a, n / 2);
return temp * temp;
}
}
法三、递推公式
因为
⌊
p
i
⌋
∗
i
=
p
−
p
m
o
d
i
\lfloor\frac{p}{i}\rfloor*i=p-p\ mod\ i
⌊ip⌋∗i=p−p mod i
即
⌊
p
i
⌋
∗
i
=
−
p
m
o
d
i
\lfloor\frac{p}{i}\rfloor*i=-p\ mod\ i
⌊ip⌋∗i=−p mod i
因此
i
−
1
=
(
−
p
m
o
d
i
)
−
1
∗
⌊
p
i
⌋
i^{-1}=(-p\ mod\ i)^{-1}*\lfloor\frac{p}{i}\rfloor
i−1=(−p mod i)−1∗⌊ip⌋
可以得到递推公式
#include<bits/stdc++.h>
#define int long long
#define _0for(i, a) for(int i = 0; i < (a); ++i)
#define _1for(i, a) for(int i = 1; i <=(a); ++i)
using namespace std;
int ans[1000]={0,1};
main(void)
{
int n,p;
cin>>n>>p;
printf("1\n");
for(int i=2;i<=n;i++)
{
ans[i]=(p-(p/i))*ans[p%i]%p;
}
cout<<ans[666]<<endl;
}
除法分块
欧拉定理
如果a和n互质
扩展欧拉定理
求欧拉函数
int phi(int n)
{
int ans=n;
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)
{
ans=ans/i*(i-1);//这是一个p,注意先除再乘,防止炸int
while(n%i==0) n/=i; //把质数次方因子筛没了,就不会错了
}
}
if(n>=2) ans=ans/n*(n-1);//最后有可能剩下
return ans;
}
裴蜀定理
P4549 【模板】裴蜀定理
若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。
它的一个重要推论是:a,b互质的充要条件是存在整数x,y使ax+by=1。