数论的杂七杂八
数论
最大公约数 ( )
- 由欧几里得定理可知gcd(b,a mod b)
ll gcd(ll a,ll b)
{
if(b == 0) return a;
else return gcd(b,a%b);
}
- 顺便得出两数的最小公倍数
ll lcm(ll a,ll b)
{
return (a/gcd(a,b))*b;
}
- 多个数时,求任意两个的最大公约数和最小公倍数,用这两个数再继续结合剩余的数求最大公约数和最小公倍数,最后的结果就是多个数的最大公约数和最小公倍数了
欧拉函数
定义:表示的是小于等于n和n互质的数的个数。记作
思路:先假设答案为n,分解质因数,如果这个质因数为x,那么这个答案就变成了 倍(因为少了质因数那一部分 )
- 代码:
ll f_ol(ll x)
{
ll ans = x;
for(int i = 2;i*i <= x;i++)
{
if(x%i==0)
{
ans = ans/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) ans = ans/x*(x-1);
return ans;
}
莫比乌斯反演
赛瓦维斯特定理
已知 为大于1的正整数, ,则使不定方程 不存在非负整数解的最大整数
- 0a中间是空的,加上一个b后0a中有了一个数,以此类推要填满需要(a-1)个b,所以(a-1)b后的数都被填上了,而(a-1)b之前的(a-1)b-a不存在所以
扩展欧几里得
作用:求 的可行解
-
设
满足 -
又
, -
可得
-
即
-
即
-
最后b肯定为0,此时
所以赋值 再递归回去
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
return;
}
逆元
费马小定理
- 若p为素数,gcd(a,p) = 1,则
- 所以
- 即
是a的逆元,而 可以用快速幂来求
ll qpow(ll a,ll b)//b = p - 2
{
ll ans = 1;
a = (a % p + p) % p;
for(;b;b >>= 1)
{
if(b&1) ans = (a*ans)%p;
a=(a*a)%p;
}
return ans;
}
线性逆元
- 首先1的逆元为1
ll ny[MAXN];
void pre_ny()
{
ny[1] = 1;
for(int i = 2;i <= n;i++){
ny[i] = (ll)(p - p / i)*ny[p % i] % p;//p - p / i是为了防止负数
}
}
等比数列求和公式
ll sum_mul(ll a1,ll n,ll q)//q > 1时
{
return ((((qpow(q,n) + p - 1) % p) * fmx(q - 1) % p) * a1) % p;
}
组合数
阶乘逆元
ll jcny[MAXN];
void pre_jcny()
{
jcny[0] = jcny[1] = 1;
for(int i = 2;i <= n;i++){
jcny[i] = (jcny[i - 1] * ny[i]) % p;
}
}
阶乘
ll jc[MAXN];
void pre_jc()
{
jc[1] = 1;
for(int i = 2;i <= n;i++){
jc[i] = (jc[i - 1] * i) % p;
}
}
组合数
ll C(ll n,ll m)
{
return ((jc[n]*jcny[m])%p)*jcny[n-m])%p;
}
中国剩余定理
用于计算以下形式的同余方程(所有数互素时)
过程:
- 1.计算所有模数的积n
- 2.计算
- 3.计算
- 4.计算
(不取模) - 5.
=求和
int ci[MAXN],ni[MAXN];
ll CRT(int cnt)
{
ll n = 1,ans = 0;
for(int i = 1;i <= cnt;i++) n*=ni[i];
for(int i = 1;i <= cnt;i++)
{
ll m = n / ni[i],mm,t;
exgcd(m,ni[i],mm,t);
ans = (ans + ci[i]*mm*m%n)%n;
}
return (ans%n + n) % n;
}
拓展中国剩余定理
- 中国剩余定理考虑了所有数互质的情况,那么如果不互质,结果为多少呢?
- 解方程
-
- 如果
为 的整数倍,则有解,通过拓展欧几里得求解,然后乘上倍数,在返回带回原来的式子,得到
ll a1 = a[1],n1 = n[1];
bool flag = true;
for(int i = 2;i <= m;i++)
{
ll a2 = a[i],n2 = n[i],t1,t2;
exgcd(n1,n2,t1,t2);
if((a1-a2)%gc!=0)
flag = false;
t1 = t1*(a1-a2)/gc;
x = (n1*t1+x);
n1 = n1/gc*n2;
t1 = (t1%n1+n1)%n1;
}
- 可以#define ll __int128以防爆
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效