数论笔记Ⅰ
数论笔记Ⅰ
前言
数论专题,2022清北学堂所授,当然他讲课的课件不敢恭维,所以全部都是自学的((
Link
此处 PDF
版本,可能有些许错误在写的时候写错了,望指正。
Latex 修好啦!
同余
若 为两个整数,且他们的差 能被某个自然数 所整除,则称 和 关于 同余,记作 。它意味着 。
一些性质:
-
若 ,则 。
-
若 ,则 。
-
若 ,则 。
-
若 ,则 。
-
若 则 。
-
若 ,且 互质,则 。
(感谢梓苏的友情赞助)
欧几里得算法(辗转相除法)
一条性质:,,则 ,显然。
对于减法,设 ,则我们需要减 次,但是发现最后的 完全可以用取模取出来的。
所以得到了
int Gcd(int a,int b){return !b?a:Gcd(b,a%b);}
如果又有某个毒瘤卡你,让你每次取模的 都恰好小于 ,复杂度在 级别,单次最坏复杂度 。
扩展欧几里得算法
定理:如果任意整数 和 都不为 ,则 是 与 的线性组合集中的最小正元素。
我们先证一下这个定理。
证明:设 是线性组合集中的最小正元素,则 ,再设 ,则 ,所以 也是 与 的线性组合,由 为最小正元素,则 一定为零,同理可证 也为零,则 是 和 的公约数,则 ,又因为 是 的线性组合,则 ,则 ,所以 。
int Exgcd(int a,int b,int &x,int &y){
if(!b){x=1,y=0;return a;}
int res=Exgcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
return res;
}
由上面飞鼠斐蜀定理可知, 一定有解。根据欧几里得算法,,所以(一把子式子):
将 用除法表示,则
当 时,一定有 ,递归回去即可,于是有了上面代码。
是可以求多解的,感谢 的深情讲解。
显然把第一个式子化出来是和第二个式子等价的,但是为什么要 和 呢?因为这俩玩意是令原式成立的最小的整数.
所以 的通解是
逆元
推销自己博客不过分吧。
质数筛
从娃娃时我们就学筛质数
for(int i=2;i<=sqrt(x);i++) if(!(x%i)) return 0;
复杂度为
而后学的是埃筛,就是筛到一个数,把他的倍数全干掉喽。
void Is_prime(int n){
memset(vis,true,sizeof vis);
for(int i=2;i<=n;i++){
if(!vis[i]) continue;
for(int j=i*i;j<=n;j+=i)
vis[j]=false;
}
}
有兴趣可以看复杂度怎么证明,反正我没兴趣Eratosthenes筛法时间复杂度分析_Gavin_Nicholas
大概是?
有的时候毒瘤出题人卡你俩 ,所以我们有线性的欧拉筛。
int tmp[MAXN], Cnt = 0;
bool vis[MAXN];
void Init(int limit) {
for(int i = 2; i <= limit; ++i) {
if(!vis[i]) tmp[++ Cnt] = i;
for(int j = 1; j <= Cnt && i * tmp[j] <= limit; ++j) {
vis[i * tmp[j]] = true;
if(i % tmp[j] == 0) break;
// 欧拉筛每次都用最小质因子去筛每一个数
// 在这里,因为 i 里面有 tmp[j] 这个因子,所以对于后面的 i * tmp[k] 来说
// 可以拆成 i/tmp[j] * tmp[j] * tmp[k],而 tmp[j] < tmp[k]。
// 所以要 break;
}
}
}
再次感谢梓苏
求解模线性方程
模线性方程即为 对 进行求解。
定理:方程 与方程 是等价的,有整数解的充要条件是
第 眼大雾,第 眼还是大雾,第 眼依然大雾
证明一下,对于一个模线性方程,设,则有,两项作差得, ,移项得 ,令 ,式子为 ,这玩意怎么这么眼熟?草,斐蜀定理,所以使式子有解要满足 ,证毕。
那这玩意?扩欧搞出一组 的解。
两遍同时除以 再乘上 即可。
bool Co_eq(int a,int b,int c,int &x,int &y){
int t=Exgcd(a,b,x,y);
int k=c/t;
if(!(c%t)) return false;
x*=k;y*=k; return true;
}
中国剩余定理(Chinese remainder theorem、CRT)
引入都见过
《孙子算经》:“今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?”
化成式子就是这个样子
一个整数除以3余2、除以5余3、除以7余2,求这个整数。
答案:23
解法:由于除以3余2,因此加上一个140;由于除以5余3,因此加上一个63;由于除以7余2,因此加上一个30;这三个数的和是140+63+30=233,再减去210,就得到了23了。
这么说吧,只要是除以3余了一个1,就加上一个70;只要是除以5余了一个1,就加上一个21;只要是除以7余了一个1,就加上一个15。然后累加。超过了106就减去105就行了。
当然你可以手算这个,那数大了呢,式子多了呢?
中国剩余定理登场了,老祖宗发明的,嘿。
一个问题:计算一个整数 ,使得它满足除以 余 、除以 余 、除以 余 。
如果能够找到三个整数 使得:
令 ,易得
,
称 为问题 的解,看出三个问题的本质事类似的。
对于问题 继续分解,如果能找到一个整数 满足
那么令 ,很显然这样的 满足 ,所以我们扩展问题,定义新三个问题为
这三个问题的本质是相同的,如果找到了 ,那么就可以取 。
以问题 ①-① 为例,就是寻找一个整数 使得
.
于是 一定是 的倍数,假设 ,则有 ,这 是什么?就是 的逆元,将这个 记作,那此时 就等于 ,恰好就是 ,对应了上面的解法中的 。
以此类推,问题①-②的解答就是 ,恰好就是
问题①-③的解答就是 ,恰好就是 ,都与上面对应。
所以将问题的分解复原,可得:
最后注意到 也满足条件,因此要计算最小负整数,只需要 即可。
如果有多组解满足条件呢?他们之间又有什么联系?
假设 都满足 “除以 余 、除以 余 、除以 余 ”。观察发现 满足 “除以 余 、除以 余 、除以 余 ”。因此 一定是 的倍数,也就是说在模 的意义下,通过分解,组合解答的 恰是唯一解。
把这个问题一般化:假设整数 ,且两两互质,则对于任意 ,方程组:
都存在整数解,若 同时满足该方程组,必有 ,其中
具体而言,将上面过程表示成式子即:
int Exgcd(int a,int b,int &x,int &y){
if(!b){x=1;y=0;return a;}
int Gcd=Exgcd(b,a%b,x,y);
int t=x;
x=y;y=t-a/b*y;
return Gcd;
}
signed main() {
n=read();int Mul=1;
for(int i=1;i<=n;i++){
M[i]=read();Mul*=M[i];Y[i]=read();
}
for(int i=1;i<=n;i++){
int qwq=Mul/M[i];
int x=0,y=0;
Exgcd(qwq,M[i],x,y);
Ans+=Y[i]*qwq*(x>=0?x:x+M[i]);
}
return print(Ans%Mul),0;
}
套式子来就行,注意变量别混了就行。
扩展中国剩余定理(Extended Chinese remainder theorem,EXCRT)
我们知道中国剩余定理用来求解同于方程组必须要求模数互质,但是如果某个啥币出题不让他们互质呢?
自为风月马前卒:“把出题人吊起来干一顿。”
和 其实没多少关系,一个用 ,另一个是构造。
先列出这一把子方程
我们选择上面俩看看能不能合成,于是得到下面一个方程组
我们的到了一个等式: ,移项得到 ,是不是 的形式?自然阔欧搞上,我们用扩欧求出 的通项,但是根据扩欧的限制条件,必须有 ,如果前提不满足,则这个同余方程组无解。我们设 为 的两个特解,将式子两边都乘上 ,就知道上述式子 ,带回去,得到:
显然满足这个方程组的不只一组,并且每一组都对应一个 ,所以我们能知道每两个解就是 和的倍数,所以 一定是 的倍数,即 是 的倍数。
感谢梓苏的讲解。为什么呢,设有 和 ,带入一式,得到两式作差, ,得到 是 的倍数,同理得到 也是 的倍数。
所以每两个解 一定是的倍数,那就是,所以 一定是 的倍数。
又因为 ,这样我们就将上面两个同余方程合成为 。
完事,难。
费马小定理
内容:若 为质数, ,则
证明自行百度,其实是我不会。
徐佬给出了解释,我们来看他怎么说:
图在PDF里。
欧拉定理
实质上是对费马小定理的拓展。
内容:若正整数 互质,则
证明自行百度,梓苏也不会了。,给个欧拉-费马小定理定理(定理证明)
推论:若 互质,则对于任意正整数 ,有
证明一下,设 ,则 。前方高能
这式子很明白了吧。
扩展欧拉定理:
,当 不一定互质且
,当 不一定互质且
证明详解这里,我太菜了,不会证,梓苏说记住就行?
附赠一个小推论:
推论:若正整数 互质,则满足 的最小正整数 是 的约数
欧拉函数
定义: 中与 互质数的个数叫欧拉函数,记
对 进行质因数分解
则有
特别的
证明:要求的就是 中与 不含相同质因子的数,我们先假设 只有两个质因子,假设 为 的质因子,那么 中 的倍数有,同理 有 个,我们自然要筛掉这些数,但是其中 被筛了两次,所以还要加回来,得 ,对式子稍作变换,得 ,再变得 ,然后我们采用数学归纳法类推到多项就得到上面式子。
实现:
①求单个欧拉函数,类似质数判断
根据上面函数定义式,可以得到一个在分解质因数的同时求解单个欧拉函数的方法,时间复杂度
int Get_phi(int x){
int res=x;
for(int i=2;i*i<=x;i++)
if(!(x%i)){res=res/i*(i-1);while(!(x%i)) x/=i;}
if(x>1) res=res/x*(x-1);
return res;
}
②递推打表,类似埃式筛
void Phi(int n){
for(int i=1;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[j]=phi[j]/i*(i-1);
}
}
③线性筛,类似欧拉筛质数
需要用到欧拉函数的两个性质
若有 ,且满足 ,则 .
证明:若有 ,且满足 ,说明 和 有相同的质因子,我们分析只含两个质因子的简单情况,
,,二者相除商为 ,
若有 ,且一定不满足 ,则 .
证明:若有 ,且满足 ,说明 和 一定互质,根据积性函数定义有 ,因为 为质数,则 (费马小定理),得,证毕。
void Phi(int n){ phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) Prime[++cnt]=i,phi[i]=i-1;
for(int j=1;j<=cnt&&i*Prime[j]<=n;j++){
vis[i*Prime[j]]=true;
if(!(i%Prime[j])){ phi[i*Prime[j]]=phi[i]*Prime[j];}
//说明i*Prime[j]中含有两个Prime[j]的因子,应用推论1
else phi[i*Prime[j]]=phi[i]*phi[Prime[j]];//反之推论2
}
}
}
组合数
再推销一波博客(✿◡‿◡)
多重集合的排列
, 为不同元素, 为个数。
多重集合 的 排列数为
多重集合 的全排列数为:
多重集合部分有限部分无限分母仅除有限部分阶乘乘。
一个例子:在 之间随机生成长度为 的整数序列,请问正好含有 个不同的整数的方案数,答案。
先从 个数里面选 个数,对于剩下一个位置可以是这 个数的任意一个, 个数随便排列,但是有两个重复元素,注意对 求逆元。
二项式定理
定理:
这就是二项式定理,等式右边即为 的二项式,共有 项。
叫做二项式展开式的第 项,也就是通项,通项用 表示。
, 叫做 项的二项式系数。
证明:组合证明法
将幂次拆开,
按照乘法分配律展开,直到无括号。因为每项都可以选 或者 ,因此共有 项,显然所有项都是 的形式,为了计数形如 的项的系数,必须从 个 中选取 个 (从而乘机中其余的 个项都是 ),所以 的系数是 ,证毕。
P1313:二项式定理,快速幂,费马小定理,逆元
卢卡斯定理(Lucas's theorem)
对于非负整数 和质数 ,
是 的 进制展开。
但其实我们常用这个可以与之互推的式子:
,当 时,规定
我们可以利用这个式子递归求解,递归边界就是 。其实只需要记住公式就够了,因为你可以马上写 出卢卡斯的板子。
int C(int m,int n,int p){
return m<n?0:fact[m]*inv(fact[m],p)%p*inv(fact[m-n],p)%p;
}
int lucas(int m,int n,int p){
return !n?1:lucas(m/p,n/p,p)*C(m%p,n%p,p)%p;
}
证明:设 是任意小于 的正整数,那么:,由于 且 是质数,所以存在 模 意义下的逆元,故:,显然右边是 的倍数,所以 ,由二项式定理:,由于 除了 和 的项外模 都为零(上面已证),所以 ,现在我们设 , ,那么那么 ,再由二项式定理 (咱也不知道为啥这句话不显示),而同时有(前方高能):
注意满足 的项为 ,所以上面和式一定遍历所有可能的非零项,我们再枚举 ,得到 ,为什么呢?和梓苏讨论了一会,是这样的: 能使 遍历到的范围是 到 ,即换元之后枚举的 ,根据二项式定理的结果,得 ,对比系数,则,,令 ,得到 ,定理得证。
扩展卢卡斯定理
自行解决,我累了。
后记
经过这几天的经历,充分的告诉了我一个事实:只有交了钱的自学最有效率!
这金牌真tm ssh??
本文作者:Gym_nastics
本文链接:https://www.cnblogs.com/BlackDan/p/15848308.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人