首页 > 其他分享 >数论浅杂谈

数论浅杂谈

时间:2022-11-04 19:55:59浏览次数:81  
标签:return gcd 数论 杂谈 整数 int ans ax

欧几里得算法

欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。
gcd(a,b)=gcd(b,a%b)

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

裴蜀定理

裴蜀定理(或贝祖定理)得名于法国数学家艾蒂安·裴蜀,说明了对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。
它的一个重要推论是:a,b互质的充分必要条件是存在整数x,y使ax+by=1.

来看一道模板题:
P4549 【模板】裴蜀定理
对应这一推论:
image
所以题目在题目限制下的最小值就是这n个数的最大公约数。

#include <bits/stdc++.h>
using namespace std;
int n;
int gcd(int a, int b) {
	return b ? gcd(b, a % b) : a;
}
int main() {
	scanf("%d", &n);
	int ans = 0, tmp;
	for (int i = 1; i <= n; i ++) {
		scanf("%d", &tmp);
		if (tmp < 0) tmp = - tmp;
		//都变为正数不影响结果
		ans = gcd(ans, tmp);
	}
	printf("%d\n", ans);
	return 0;
}

image

扩展欧几里得算法

扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。除了计算a、b两个整数的最大公约数,此算法还能找到整数x、y(其中一个很可能是负数)。通常谈到最大公因子时, 我们都会提到一个非常基本的事实: 给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数——这是众所周知的。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。
先看代码:

int exgcd(int a, int b, int &x, int &y) {
	if (b == 0) {
		x = 1; y = 0;
		return a;
	}
	int g = exgcd(b, a % b, x, y);
	int tmp = x; x = y; y = tmp - a / b * y;
	return g;
} 

推导过程:

ax + by = gcd(a, b)            	//1
bx` + (a % b)y` = gcd(b, a % b)	//2
联立1,2 得:
ax + by = bx` + (a % b)y`
ax + by = bx` + (a - a / b * b)y`
ax + by = ay` + b(x` - a / b * y`)
对比系数可得:
x = y`  y = x` - a / b * y`
所以我们可以用x`和y`倒推x和y,通过欧几里得算法,利用b = 0时
的解x = 1, y = 0往前逐步倒推,最终得到ax + by = gcd(a, b)的
一组整数解

模板题:P1082 [NOIP2012 提高组] 同余方程
code:

#include <bits/stdc++.h>
using namespace std;
int a, m, x, y;
int exgcd(int a, int b, int &x, int &y) {
	if (b == 0) {
		x = 1; y = 0;
		return a;
	}
	int g = exgcd(b, a % b, x, y);
	int tmp = x; x = y; y = tmp - a / b * y;
	return g;
}
int main() {
	cin >> a >> m;
	int g = exgcd(a, m, x, y);
	cout << (x % m + m) % m;
	return 0;
}

image

费马小定理

费马小定理(Fermat's little theorem)是数论中的一个重要定理,在1636年提出。如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。

乘法逆元的几种求法

1.扩欧

#include <bits/stdc++.h>
//扩展欧几里得算法求逆元(适用条件:a,p互质,即gcd(a,p)=1)
using namespace std;
int a, p, x, y;
int ecgcd(int a, int b, int &x, int &y) {
	if (b == 0) {
		x = 1, y = 0;
		return a;
	}
	int g = exgcd(b, a % b, x, y);
	int tmp = x; x = y; y = tmp - (a / b) * y;
	return g;
}
int main() {
	scanf("%d %d", &a, &p);
	int g = exgcd(a, p, x, y);
	//用扩欧求ax+bp=gcd(a,p)=1的一组解,此时的x就是a在模p意义下的逆元
	printf("%d\n", (x % p + p) % p);
	return 0;
}

2.费马小定理

#include <bits/stdc++.h>
//费马小定理求逆元(适用条件:p为质数且a不是p的倍数)
//a在模p意义下的逆元就是a^(p-2)
using namespace std;
int a, p;
int ksm(int a, int b, int c) {//快速幂
	int ans = 1;
	a = a % c;
	while (b) {
		if (b & 1) ans = (ans * a) % c;
		a = (a * a) % c;
		b >>= 1;
	}
	return ans;
}
int main() {
	scanf("%d %d", &a, &p);
	printf("%d\n", ksm(a, p - 2, p));
	return 0;
}

3.线性递推求1~n的逆元

#include <bits/stdc++.h>//线性递推求逆元
#define ll long long
using namespace std;
const int N = 3e6 + 10;
int n, p, inv[N];
int main() {
	ios::sync_with_stdio(false);
	cin >> n >> p;
	inv[1] = 1;
	for (int i = 2; i <= n; i ++)
		inv[i] = (ll) (p - p / i) * inv[p % i] % p;
	for (int i = 1; i <= n; i ++)
		cout << inv[i] << '\n';
	return 0;
}

4.倒推

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e6 + 10;
int n, p;
ll inv[N], fac[N];
ll ksm(ll x, int y) {
	ll ans = 1;
	while (y) {
		if (y & 1) ans = ans * x % p;
		x = x * x % p;
		y >>= 1;
	}
	return ans;
}
int main() {
	ios::sync_with_stdio(false);
	cin >> n >> p;
	fac[0] = 1;
	for (int i = 1; i <= n; i ++) fac[i] = fac[i - 1] * i % p;
	inv[n] = ksm(fac[n], p - 2);
	for (int i = n; i >= 2; i --) inv[i - 1] = inv[i] * i % p;
	for (int i = 1; i <= n; i ++)
		cout << fac[i - 1] * inv[i] % p << '\n';
	return 0;	
}

image

标签:return,gcd,数论,杂谈,整数,int,ans,ax
From: https://www.cnblogs.com/YHxo/p/16858835.html

相关文章

  • 杂谈篇之我是怎么读源码的,授人以渔
    开心一刻今天上课不小心睡着了,结果被老师叫起来回答问题,这是背景无奈之下看向同桌寻求帮助,同桌小声说到选C,结果周围的人都说选C,向同桌投去一个感激的眼神后大声说道......
  • 固态Lidar-ADAS-DSP-芯片杂谈
    固态Lidar-ADAS-DSP-芯片杂谈参考文献链接https://mp.weixin.qq.com/s/83ECnBwIGD-Fz5F2Mj5HGQhttps://mp.weixin.qq.com/s/aXNcOnKrEW_pajY6NrCZuwhttps://mp.weixin.......
  • 最短路问题杂谈
    感觉这类问题好多变形,记录一下,方便复习。P1522[USACO2.4]牛的旅行CowTours由于题目的N很小,且要求任意两点之间距离,很容易想到一下暴力做法:求出题目的联通块,记id[......
  • Codeforces - 1391C - Cyclic Permutations(思维 + 组合数学 + 数论 + 图论、*1500)
    1391C-CyclicPermutations(⇔源地址)目录1391C-CyclicPermutations(⇔源地址)tag题意思路AC代码错误次数:0tag⇔思维、⇔组合数学、⇔数论、⇔......
  • 提高组数论速查
    同余与剩余系设有整数\(n_1,n_2,m\)满足\(\existq_1,q_2,r\in\Z,n_1=mq_1+r,n_2=mq_2+r\),则称\(n_1,n_2\)模\(m\)同余,记作\(n_1\equivn_2\pmodm\)。称所......
  • 【XSY4350】摆(行列式,数论,杜教筛)
    题面摆题解首先我们将原矩阵写成\(A+B\),其中\(B\)全是\(C\),那么\(A\)的第\(i\)行就只有其倍数处有值,且\(A_{i,i}=1-C,A_{i,j(i|j\landi\neqj)}=-C\)。那么......
  • 221029 | 杂谈:CQ S 组整大活
    统计工具:VSCode因为J组烂活和无意义内容(话说这俩好像是同一个意思)太多,所以就只开S组了。总览注:统计结果表现形式为了方便,统一描述,实际搜索时统计了所有情况(不区分......
  • Google-高精地图-riscv-收购Twitter杂谈
    Google-高精地图-riscv-收购Twitter杂谈参考文献链接https://mp.weixin.qq.com/s/xk4RvcYVXOJ-1WfSCcvnPQhttps://mp.weixin.qq.com/s/24LD5uKTkAG_lIYHWmpX_ghttps://......
  • 【CQOI2017】小Q的表格(数论,分块)
    题意:有一个无限大的整数表格\(f\)满足以下两条法则:\(f(a,b)=f(b,a)\)。\(b\timesf(a,a+b)=(a+b)\timesf(a,b)\)。初始时\(f(a,b)=a\timesb\)。有\(m\)次修改......
  • 数论-费马小定理 学习笔记
    1.定理内容如果p是一个质数,而整数a不是p的倍数,则有。即:若为素数,,则。第二种表述形式:对于任意整数,有。在实际的应用中,我们最多用的是第二种表述形式。2.证明设一个质数为......