欧几里得

《信息安全数学基础一》第一章笔记

被刻印的时光 ゝ 提交于 2020-03-26 03:15:25
《信息安全数学基础一》第一章笔记 目录 《信息安全数学基础一》第一章笔记 整除 素数,合数 素数判别 筛法 埃式筛 欧拉筛 进制转换 最大公因数与最小公倍数 欧几里得算法 贝祖等式 拓展欧几里得算法 算术基本定理 整除 定义 在整数域内,若 \(a = q\cdot b\) ,则 \(b\) 整除 \(a\) ,记作 \(a | b\) 性质 若 \(a | b,\ b | c\) ,则 \(a | c\) 若 \(c | a_{i},\ i = 1,\ 2,\ ..,\ n\) 则 \(c\) 也整除 \(a_{i}\) 的线性组合 素数,合数 素数定义 除了 \(1\) 和自身外,没有因数的数,称之为素数,也称为质数,其他数被称为合数。 \(2\) 是最小的素数 素数判别 一个定理 对于合数 \(n\) ,必然存在不超过 \(\sqrt{n}\) 的质因子。 设 \(n = pq\) ,设 \(p\) 是最小因子,则 \(p\leq q\) 则 \(n = pq \geq p^{2}\) 所以 \(p\leq \sqrt{n}\) 假设 \(p\) 是合数,则可以继续进行分解,与题设不符,所以 \(p\) 是质数。 定理推论 对于一个数 \(n\) ,若其不存在不超过 \(\sqrt{n}\) 的质因子,那么其为素数。 素数平凡判别 枚举 \(2-\sqrt{n}\) 内的素数

拓展欧几里得算法

◇◆丶佛笑我妖孽 提交于 2020-03-25 02:52:48
先贴个模板: 1 void gcd(LL a,LL b,LL &d,LL &x,LL &y) 2 { 3 if (!b) 4 { 5 x=1; 6 y=0; 7 d=a; 8 } 9 else 10 { 11 gcd(b,a%b,d,y,x); 12 y-=a/b*x; 13 } 14 } 下面给出我对这个算法的理解: 现在要解ax+by=gcd(a,b) 假设我们已经解出了 bx 0 + (a%b)y 0 =gcd(a,b) (1) 令y=x 0 -> ay 0 + by = gcd(a,b) (2) (2)-(1)得到 (a-a%b)y 0 + b(y-x 0 )=0 整理得到 y=x 0 -((a-a%b)/b)y 0 = x 0 - a/b*y 0 = x 0 - a/b * x 根据上面的递归,返回的时候x=y0,y=x0 所以y需要再减去 a/b*x 函数结束时就可以得到一组解了。那么如何得到其他解呢? 首先令 d=gcd(a,b) a'=a/d b'=b/d ax+by=d 设a(x+x 0 ) + b(y+y 0 )=d 那么相减得到 ax 0 +by 0 =0 -> y 0 =-a/b * x 0 = -a'/b' * x 0 y 0 和x 0 都是整数,所以x 0 必定是b'的倍数. 即x 0 =k*b' 因此对于方程ax+by=d , 让x=x+b' y=y

同余问题(一)——扩展欧几里得exgcd

♀尐吖头ヾ 提交于 2020-03-13 15:36:33
前言 扩展欧几里得 算法是一个很好的解决同余问题的算法,非常实用。 欧几里得算法 简介 欧几里得算法,又称辗转相除法。 主要用途 求最大公因数 \(gcd\) 。 公式 \(gcd(a,b)=gcd(b,a\%b)\) 公式证明 \(a\) 可以表示成 \(a=kb+a\%b\) ( \(k\) 为自然数)。 假设 \(g\) 是 \(a,b\) 的一个公约数,则有 \(g|a, g|b\) 。 \(\because a\%b=a-kb\) , \(\therefore g|(a\%b),\therefore g\) 是 \(b,a\%b\) 的公约数。 综上所述, \(a,b\) 和 \(b,a\%b\) 的公约数是一样的,其 \(gcd\) 也必然相等。 代码实现 inline int gcd(int x,int y) {return y?gcd(y,x%y):x;} 扩展欧几里得算法 简介 扩展欧几里得建立于欧几里得算法的基础上。 (该算法的升级版 徐xgcd 有待 XuRuiYang 奆佬发明) 主要用途 对于已知a,b求解x,y使其满足ax+by=gcd(a,b)。 解法 我们可以对 \((a,b)\) 不断辗转相除。 根据欧几里得算法,最后剩下的两个数一定为 \((gcd(a,b),0)\) , 显然,此时 \(x=1,y=0\) 是原式的一组解。 现在,我们需要考虑

浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用

与世无争的帅哥 提交于 2020-03-12 08:59:08
一、欧几里得算法及其证明 1.定义: 欧几里得算法又称辗转相除法,用于求两数的最大公约数,计算公式为GCD(a,b)=GCD(b,a%b); 2.证明: 设x为两整数a,b(a>=b)的最大公约数,那么x|a,x|b; ①由整数除法具有传递性(若x能整除a,x能整除b,那么x可整除a,b的任意线性组合)知x|a-b; ②设x不是b的因子,则x不是b和a-b的公因子;设x不是a的因子,则x不是b和a-b的公因子;所以可以得出GCD(a,b)=GCD(b,a-b); ③由a>=b知,a可表示为a=b*q+r;则a减去q个b剩下的数字即为r,所以GCD(a,b)=GCD(b,a%b); 3.一般代码: (1)递归形式: int gcd(int a,int b){return b?gcd(b,a%b):a;} (2)迭代形式: int gcd(int a,int b){ for(;;) { if(b==0)return a; int temp=a%b; a=b; b=temp; } } 4.几个性质: (1)若GCD(a,b)=1,那么a,b两数互质。 (2)GCD(a,2a)=a; (3)GCD(a,0)=a; (4)GCD(a,b)=GCD(-a,b)=GCD(a,-b)=GCD(-a,-b); (5)LCM(a,b) GCD(a,b)=a b(LCM为两数小公倍数); (6)GCD

@hdu - 6584@ Meteor

偶尔善良 提交于 2020-03-06 00:48:17
目录 @description@ @solution@ @accepted code@ @details@ @description@ 询问第 k 小的分子分母 ≤ n 的既约分数。 Input 第一行包含一个整数 T(T≤10^2),表示数据组数。 接下来 T 行每行两个整数 n, k,表示一组询问。保证询问的答案在 (0,1] 范围内。 Output 输出 T 行,每行包含一个分数 p/q,要求 gcd(p, q) = 1。 Sample Input 5 4 6 5 1 9 9 3 4 7 11 Sample Output 1/1 1/5 1/3 1/1 3/5 Hint 杭电支持 __int128。 @solution@ 寻找第 k 小,不难想到使用二分法。 则假如二分到一个值 x,≤ x 的既约分数可以用如下式子计算: \[ans = \sum_{i=1}^{n}\sum_{j=1}^{\lfloor x*i\rfloor}[gcd(i, j) = 1]\] 对其进行反演可得: \[ans = \sum_{i=1}^{n}\sum_{d=1}^{d|i}\mu(d)*\lfloor\frac{x*i}{d}\rfloor \\ = \sum_{a*b\le n}\mu(a)*\lfloor x*b \rfloor \\ = \sum_{i=1}^{n}\mu(i)*\sum

贝祖公式证明

懵懂的女人 提交于 2020-03-02 00:21:02
贝祖公式证明 前言:最近写一道算法题的过程中,遇到了关于贝祖公式的题目,发现其实很简单。根据前人总结证明方法,进行归纳,在此证明。 一. 欧几里得算法 要证明贝祖公式,首先需要知道欧几里得算法,欧几里得算法也叫辗转相除法,用于求两个整数之间的最大公约数。 公式如下: gcd(a,b) = gcd(b,a mod b) (a>b 且 a mod b 不为0) 证明如下: 因为a>b,所以a可以表示为kb+r,r=a mod b 从左往右看,假设d是a,b的一个公约数,那么a和b都可以被d整除,r=a-kb,自然r也可以被d整除,所以d也是(b,r),也就是(b,a mod b)的公约数。 反过来,假如d是b和r = a mod b的一个公约数,则有b和r都可以被d整除,根据a=kb+r,自然a也可以被d整除,所以d也是(a,b)的公约数。 因此,(a,b)和(b,a mod b)的公约数一致,自然最大公约数也一致。 欧几里得算法应用:不断运用该算法,即“两个整数的最大公约数,等于其中较小的那个数和较大数对较小数取模结果的最大公约数。” 将两个数缩小,直到一个数为0,另一个数就是最小公约数 eg,求12和42的最大公约数,gcd(12,42) = gcd(12,6)=gcd(6,0)=6 二、贝祖公式 根据前面推导的欧几里得算法,贝祖公式就应运而生啦!

扩展欧几里得算法

我怕爱的太早我们不能终老 提交于 2020-03-01 12:21:43
扩展欧几里得算法(欧几里得算法即辗转相除法) 裴蜀定理:有一对正整数a, b,那么一定存在整数x, y,使得 ax + by = (a, b)最大公约数。 举例:存在ax + by = d,则d是a和b的最大公约数的倍数。 Example 给定nn对正整数ai,biai,bi,对于每对数,求出一组xi,yixi,yi,使其满足ai∗xi+bi∗yi=gcd(ai,bi)ai∗xi+bi∗yi=gcd(ai,bi)。 输入格式 第一行包含整数n。 接下来n行,每行包含两个整数ai,biai,bi。 输出格式 输出共n行,对于每组ai,biai,bi,求出一组满足条件的xi,yixi,yi,每组结果占一行。 本题答案不唯一,输出任意满足条件的xi,yixi,yi均可。 数据范围 1≤n≤1051≤n≤105, 1≤ai,bi≤2∗1091≤ai,bi≤2∗109 输入样例: 2 4 6 8 18 输出样例: -1 1 -2 1 //欧几里得算法 #include <iostream> using namespace std; int exgcd(int a, int b, int &x, int &y) { //return b ? gcd(b, b % a) : a; if (!b) //如果b = 0,ax + by = a { //得到一组解 x = 1, y = 0;

hdu1576(扩展欧几里得)

两盒软妹~` 提交于 2020-02-28 11:50:10
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 题目:要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。 Input 数据的第一行是一个T,表示有T组数据。 每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。 Output 对应每组数据输出(A/B)%9973。 Sample Input 2 1000 53 87 123456789 Sample Output 7922 6060 题目分析: 1.已知n,B的值,要求(A/B)%9973的结果。其中n=A%9973,gcd(B,9973)=1; 假设 ans 是(A / B)%9973的结果,即(A / B)%9973=ans 可知存在一个x使得 9973*x+ans=(A / B) 所以:A=9973*Bx+ans*B..........(1) 又因为 n=A%9973,所以存在一个y ,使得A=9973*y+n.............(2) 由(1)(2)式得9973*y+n=9973*Bx+ans*B 转换后得:n=9973Bx+ans*B-9973y=9973(Bx-y)+ans*B====>(两边同时除以n后得到)(ans/n)*B+(Bx-y)

hdu 1576 A/B 拓展欧几里得算法

孤街浪徒 提交于 2020-02-28 11:47:58
A/B Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2390 Accepted Submission(s): 1731 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。 Input 数据的第一行是一个T,表示有T组数据。 每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。 Output 对应每组数据输出(A/B)%9973。 Sample Input 2 1000 53 87 123456789 Sample Output 7922 6060 Author xhd   对于拓欧我用的一点也不熟练,特别是限制解必须为正数时,而本题规定了b,9973互质,直接取模至正数,还变简单了。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long qword; qword ext_gcd(qword a

扩展欧几里得算法(exgcd)

房东的猫 提交于 2020-02-12 18:06:52
前提:知道普通欧几里得算法(辗转相除法)。 #include<bits/stdc++.h> using namespace std; long long x, y;//目前方程真正的解 void exgcd(long long a, long long b) { //当前目的:求解 ax + by = gcd(a, b) 这么一个方程 if(b == 0) //a, b不断改变的过程中,b最终必然会成为0 { //在 b = 0 时方程还要成立? 使 x = 1, y = 0 ,必然成立 x = 1; y = 7; //建议返回0。不过y = 7能AC,证明了最后一个等式不受最后一个y影响 return; } exgcd(b, a % b);//把下一层系数传进去(先求下一个方程的解 ) //现在我们已经拿到了下一个方程的解x, y long long tx = x;//暂时存一下x,别丢了 x = y; y = tx - a / b * y; } int main() { long long a, b; cin >> a >> b; exgcd(a, b); x = (x % b + b) % b;//我们求出来的x必然满足方程,但不一定是最小正整数解,所以要进行答案处理 printf("%lld\n", x); return 0; } typedef long long LL;