数论进阶

扩展欧几里得算法

裴蜀定理(Bézout's identity)

\(1\) :对于任意整数 \(a\),\(b\) ,存在一对整数 \(x\) ,\(y\) ,满足 \(ax+by=GCD(a,b)\) 。

2:对于任意整数 \(a\),\(b\) ,二元一次不定方程 \(ax+by=c\) 有整数解 \((x,y)\) 当且仅当 \(GCD(a,b)|c\) 。

扩展欧几里得算法(Extended Euclidean algorithm)

首先,我们来回顾一下欧几里得算法:

void gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}

扩展欧几里得算法是用于在已知 \(a\),\(b\) 的情况下求一组解 \(x\),\(y\) ,使他们之间满足:\(ax+by=GCD(a,b)=d\)。(GCD即最大公约数)。我们要计算的是 \(a\) 和 \(b\) 的最大公约数,并求出 \(x\) 和 \(y\) 使得 \(ax+by=d\)。

此时,我们已经计算出了下一个状态:\(b\) 和 \((a\%b)\) 的最大公约数,并求出了一组 \(x_1,y_1\) 使得:\(bx_1+(a\%b)y_1=d\) 。而相邻状态之间的关系是怎样的呢?

我们知道:\(a\%b=a-\lfloor{a \over b} \rfloor *b\) ,所以有:

\[\begin{align}
d&=b * x_1 +[a-\lfloor {a\over b} \rfloor *b]*y_1\\
&=b*x_1+a*y_1-\lfloor{a\over b}\rfloor * b * y_1\\
&=a*y_1+b*(x_1-\lfloor {a\over b} \rfloor * y_1)\\
\end{align}
\]

所以:\(x=y_1,y=x_1-\lfloor{a\over b}\rfloor *y_1\) 。

特别的:在欧几里得算法执行到最后一步,即 \(b=0\) 时,我们可以得到一对整数 \(x=1,y=0\) ,使得 \(a*1 + 0*0=GCD(a,0)\) 。

由此便可以写出扩展欧几里得的模板(exGCD),代码如下:

typedef long long ll;
ll exgcd(ll a,ll b,ll &x,ll &y){
if (b==0) {
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return d;
}

线性同余方程

乘法逆元

中国剩余定理

扩展中国剩余定理

原根

BSGS

代码如下:

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
int log_mod(ll a,ll b,ll n) {
if (b==1) return 0;
gp_hash_table<int,int> hash;
int t=ceil(sqrt(n));
ll z=1;
for (int i=0; i<t; i++) {
hash[b*z%n]=i;
z=z*a%n;
}
int now=1;
for (int i=1; i<=t; i++) {
now=now*z%n;
if (hash.find(now)!=hash.end()) {
return i*t-hash[now];
}
}
return -1;
}

高次剩余

很遗憾,这个内容作者在OIWIKI上找到,而百度百科上的内容也不全。

为了学习高次剩余部分的内容,我们先给出一个问题:

求解 \(x^a\equiv b (mod\ p)\)

我们规定:\(p\) 是个质数。

在学习了原根方面的知识后,我们可以得知:p一定存在一个原根,我们假设这个原根为 \(g\) 。因此,对于模 \(p\) 意义下的任意的数 \(x(0\le x <p)\) 有且仅有一个数满足 \(i(0 \le i<p-1)\) 满足 \(x=g^i\) 。

接下来将会列出解决方案。

方案一

我们令 \(x=g^c\) ,由于 \(g\) 是 \(p\) 的原根(而这个 \(g\) 和 \(c\) ,通过之前学习的方法,我们一定可以找到),那么问题将转化为求解 \((g^c)^a \equiv b (\mod p)\) ,我们可以在将其变换,得到:

\[(g^a)^c\equiv b(mod\ p)
\]

于是,这就变成了离散对数的基本模型了,我们可以用 \(BSGS\) 解决这道题,只要在 \(O(\sqrt p)\) 内解出 \(c\) ,这样就可以得到原方程的一个特解 \(x_0\equiv g^c (mod\ p)\)

方案二

仍然令 \(x=g^c\) ,此时,我们在规定 \(b=g^t\) ,于是我们得到:

\[g^{ac}\equiv g^t (mod\ p)
\]

方程两边同时取离散对数后得到:

\[ac\equiv t (mod\ \varphi (p))
\]

而方程中的 \(t\) 可以通过 \(BSGS\) 求解 \(g^t \equiv b (mod\ p)\) 得到,于是这就转化成了一个线性同余方程的问题。这样便可解除一个特解 \(c_0\) ,\(c\) 的所有通解为 \(c_0+k\frac {\varphi(p)} {gcd(a,\varphi(p))}\) ,其中 \(k\) 为整数。

于是 \(x\) 的通解为: \(g^{c_0+k\frac {\varphi(p)} {gcd(a,\varphi(p))}}\) ,而我们要求的是所有在 \([0,p-1]\) 范围内的解,可以将解一个个放进 \(vector\) 中,直到重复(可以用 \(set\) 或者 \(hash\) 来判断重复,这里我们采用的是 \(hash\) 的方法,不了解 hash 的读者可以看这里,但我们的 hash 是直接调用的,而不是手写的)

代码如下:

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
vector<int> extract_mod(int a,int b,int p){
vector<int> res;
int g=find_yg(p);
int c=log_mod(pow_mod(g,a,p),b,p);
if (c==-1) return res;
int x=pow_mod(g,c,p),t=pow_mod(g,(p-1)/gcd(a,p-1),p);
gp_hash_table<int,int> hash;
while(1){
res.push_back(x);
hash[x]=1;
x=(ll)x*t%p;
if (hash[x]==1) break;
}
return res;
}

exBSGS

代码如下:

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
int exgcd(int a,int b,int &x,int &y){
if (b==0){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return d;
}
int exBGSG(int a,int b,int n){
if (b==1) return 0;
int cnt=0,x,y;
ll w=1;
while(1){
int d=exgcd(a,n,x,y);
if (d==1) break;
if (b%d!=0) return -1;
b/=d;
n/=d;
w=w*a/d%n;
cnt++;
if (b==w) return cnt;
}
exgcd(w,n,x,y);
b=(ll)b*(x%n+n)%n;
a=a%n;
gp_hash_table<int,int> hash;
int t=ceil(sqrt(n));
ll z=1;
for (int i=0;i<t;i++){
hash[b*z%n]=i;
z=z*a%n;
}
int now=1;
for (int i=1;i<=t;i++){
now=now*z%n;
if (hash.find(now)!=hash.end()){
return i*t-hash[now]+cnt;
}
}
return -1;
}
int main(){ return 0;
}

数论进阶&#160;的更多相关文章

  1. 【数论】数论进阶-Preknowledge

    数论进阶-Preknowledge 参考资料:洛谷网校2018夏季省选基础班SX-3数论进阶课程及课件 一.整除与取整除法 1.1 定义 1.整除 \(\forall~x,y~\in~Z^+,\) 若 ...

  2. ACM进阶计划

    ACM进阶计划ACM队不是为了一场比赛而存在的,为的是队员的整体提高.大学期间,ACM队队员必须要学好的课程有:lC/C++两种语言l高等数学l线性代数l数据结构l离散数学l数据库原理l操作系统原理l ...

  3. “胡”说IC——菜鸟工程师完美进阶

    “胡”说IC——菜鸟工程师完美进阶(数十位行业精英故事分享,顶级猎头十多年来经验总结,对将入或初入IC电子业“菜鸟”职业发展.规划的解惑和点拨.) 胡运旺 编著   ISBN 978-7-121-22 ...

  4. HTML5游戏开发进阶指南(亚马逊5星畅销书,教你用HTML5和JavaScript构建游戏!)

    HTML5游戏开发进阶指南(亚马逊星畅销书,教你用HTML5和JavaScript构建游戏!) [印]香卡(Shankar,A.R.)著 谢光磊译 ISBN 978-7-121-21226-0 201 ...

  5. [转]ACM进阶计划

    ACM进阶计划  大学期间,ACM队队员必须要学好的课程有: lC/C++两种语言 l高等数学 l线性代数 l数据结构 l离散数学 l数据库原理 l操作系统原理 l计算机组成原理 l人工智能 l编译原 ...

  6. ACM进阶

    ACM队不是为了一场比赛而存在的,为的是队员的整体提高. 大学期间,ACM队队员必须要学好的课程有: l C/C++两种语言 l 高等数学 l 线性代数 l 数据结构 l 离散数学 l 数据库原理 l ...

  7. Kinect for Windows SDK开发入门(15):进阶指引 下

    Kinect for Windows SDK开发入门(十五):进阶指引 下 上一篇文章介绍了Kinect for Windows SDK进阶开发需要了解的一些内容,包括影像处理Coding4Fun K ...

  8. SQL Server 扩展事件(Extented Events)从入门到进阶(1)——从SQL Trace到Extented Events

    由于工作需要,决定深入研究SQL Server的扩展事件(Extended Events/xEvents),经过资料搜索,发现国外大牛的系列文章,作为“学习”阶段,我先翻译这系列文章,后续在工作中的心 ...

  9. 高级进阶DB2(第2版)——内部结构、高级管理与问题诊断

    <高级进阶DB2(第2版)——内部结构.高级管理与问题诊断> 基本信息 作者: 牛新庄    出版社:清华大学出版社 ISBN:9787302323839 上架时间:2013-7-3 出版 ...

随机推荐

  1. C#实现一个万物皆可排序的队列

    需求 产品中需要向不同的客户推送数据,原来的实现是每条数据产生后就立即向客户推送数据,走的的是HTTP协议.因为每条数据都比较小,而数据生成的频次也比较高,这就会频繁的建立HTTP连接,而且每次HTT ...

  2. 初识Java GUI

    1. 使用Java  Swing 显示的窗口如下 在原有代码基础上添加代码实现对窗口大小 标题等信息

  3. ShardingSphere 云上实践:开箱即用的 ShardingSphere-Proxy 集群

    本次 Apache ShardingSphere 5.1.2 版本更新为大家带来了三大全新功能,其中之一即为使用 ShardingSphere-Proxy chart 在云环境中快速部署一套 Shar ...

  4. 常用类-jdk8之前的日期和API

    一.System静态方法 点击查看代码 package com.Tang.StringDay01; import org.junit.Test; public class DateTimeTest { ...

  5. Markdown扩展语法

    目录 Markdown 语法补充 一.快速生成 HTML 表格代码 在线表格编辑器--TablesGenerator 二. 插入视频.音频或GIF 1. 视频 2. 音频 方法一 方法二 方法三 3. ...

  6. JAVA解压.Z及.ZIP文件

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress --> <dependency ...

  7. PostgreSQL下的SQL Shell(psql)工具

    首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485130&idx=1 ...

  8. SpringWeb 拦截器

    前言 spring拦截器能帮我们实现验证是否登陆.验签校验请求是否合法.预先设置数据等功能,那么该如何设置拦截器以及它的原理如何呢,下面将进行简单的介绍 1.设置 HandlerInterceptor ...

  9. 「一本通 1.1 例 4」加工生产调度(贪心算法)(luogu P1248)题解

    加工生产调度 题目描述 某工厂收到了 n n n 个产品的订单,这 n n n 个产品分别在 A.B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工. 某个产品 i i i 在 A. ...

  10. 【人工智能】【Python】Matplotlib基础

    Maplotlib 本文档由萌狼蓝天写于2022年7月24日 目录 Maplotlib (一)Matplotlib三层结构 (二)画布创建.图像绘制.图像显示 (三)图像画布设置.图像保存 (四)自定 ...