互质

欧拉函数的应用-RSA加密算法

余生长醉 提交于 2019-12-10 07:16:24
若p和q互质,令n = p*q 则ola(n) = (p-1)*(q-1) 我们知道p和q的值能轻易知道(p-1)*(q-1)的值也就是ola函数的值,但是仅仅知道n是多少,却非常难得到p和q是多少,因为当n很大时,例如有几百位时,它就有非常多的质因数,要暴力穷举很长时间。所以这就保证了RSA加密算法的可靠性。 RSA加密是非对称加密,密钥 由公钥和私钥组成。 公式为: (明文)^e % n = 密文 其中, e 是一个小于n且与n互质的数。 (密文)^d % n = 明文 d = ( 1 + k*ola(n) ) / e (在此处, k和d都必须是正整数。) 将明文的e次方对n取余后得到密文。 将密文的d次方对n取余后得到明文。 所以 加密用公钥(e, n) 解密用私钥(d, n) 你构造出一个密钥对之后,将公钥发给别人,别人通过公钥加密,在发送给你,你在用公钥解密,就完成了明文加密传输。 所以我们首先要构造两个质数p和q 则 n = p*q ola(n) =(p-1)* (q-1) 然后随机构造一个小于n并且与n互质的数 e。 得到 e n ola(n) 之后 就剩下d了 d = ( 1 + k*ola(n) ) / e 因为d和k一定是正整数 所以我们可以从1开始枚举k,直到求出的d是一个正整数。 或者是将等式变化为 d*e - k*ola(n) = 1 由扩展欧几里得求解d

欧几里得

故事扮演 提交于 2019-12-06 15:27:15
欧几里得 关于欧几里得定理这个东西,我在全网上也没有找到什么好的讲解。所以决定自己来写一写 自己都证了好久 欧几里得的应用一般是用在求 \(gcd\) 的时候用的,用辗转相除发递归求 \(gcd\) 。 相信大家一般都是直接用的,没有想过去证明它, 认为他很显然 是吧。 我最开始也是这样以为的,但是却发现自己证了好久。 肯定是我太菜了 不多废话。。。 我就只讲一下欧几里得求 \(gcd\) 的证明。 好像欧几里得就这个作用 先写出众所周知的公式: \(gcd(a,b) = gcd(b, a % b)\) 然后不断递归就行了。 现在来证明如上等式: 令 \(gcd(a, b) = c\) , 那么, \(a = c * k1\) , \(b = c * k2\) ( \(k1\) 和 \(k2\) 互质) 那么, \(gcd(a, b) = gcd(c * k1, c * k2)\) \(a % b = c * k1 % c * k2 = (k1 % k2) * c\) 上面这一步需要好好理解一下,如果 \(k1\) 和 \(k2\) 不互质的话就没有这个结论 证明如下: 原式可以展开如下 : \(c * k1 = c * k2 * t + e\) 这个 \(t\) 可以为 \(0\) ,而这个 \(e\) 就是 \(a % b\) 了 \(a % b = c * k1 - c *

中国剩余定理

不打扰是莪最后的温柔 提交于 2019-12-05 00:19:50
中国剩余定理 其实 \(EX\) 很简单,和普通几乎一样,先上普通版只是心理缓冲 为什么普通版还没淘汰啊 。 作用: 解线性同余方程 组 。 即: \[ \begin{cases} x\equiv a_1\quad(mod\;m_1)\\ x\equiv a_2\quad(mod\;m_2)\\ \quad \dots\\ x\equiv a_k\quad(mod\;m_k)\\ \end{cases} \] 限定: \(m\) 之间两两互质。 方式: 分别解: \[ \begin{cases} x\equiv a_1\quad(mod\;m_1)\\ x\equiv 0\quad(mod\;m_2)\\ \quad \dots\\ x\equiv 0\quad(mod\;m_k)\\ \end{cases} \begin{cases} x\equiv 0\quad(mod\;m_1)\\ x\equiv a_2\quad(mod\;m_2)\\ \quad \dots\\ x\equiv 0\quad(mod\;m_k)\\ \end{cases} \begin{cases} x\equiv 0\quad(mod\;m_1)\\ x\equiv 0\quad(mod\;m_2)\\ \quad \dots\\ x\equiv a_k\quad(mod\;m_k)\\ \end

素数

不想你离开。 提交于 2019-12-03 07:12:15
一、定义   素数又称质数,是指一个大于 \(1\) 的正整数,如果除了 \(1\) 和它本身外,没有其他任何约数。偶素数只有一个为 \(2\) 。   对于正实数 \(x\) ,定义 \(\pi(x)\) 为不大于 \(x\) 的素数个数,那么 \(\pi(x)\approx\frac{x}{ln(x)}\) 二、素数的判定   对于单个数或数据范围比较小时,我们采用枚举法: bool is_prime(int x) { for(int i=2;i<=sqrt(x);i++) if(!(x%i))return 0; return 1; }   对于比较大的数据范围,并且要求出范围内的所有质数,我们卡可以采用筛选法   1、 \(Eratosthenes\) 筛选法 void get_prime(int N) { memset(v,0,sizeof(v)); for(int i=2;i<=N;i++) { if(v[i])continue ; prime[++cnt]=i; for(int j=i;j<=N/i;j++)v[i*j]=1; } }   不过我们发现这个筛法的效率并不高,因为它会重复筛选同一个质数。因此,就有了第二种筛法——快速线性筛法,它的复杂度几乎是线性的。 void get_prime(int N) { memset(v,0,sizeof(v)); for

HDU - 2588 GCD (欧拉函数)

匿名 (未验证) 提交于 2019-12-02 23:55:01
原题链接 题意: 给你两个数 \(N,M\) 你要求出 符合条件 \(GCD(X,N)>=M,\space (1<=X<=M)\) 中 \(X\) 的个数 思路: 一开始没有往欧拉函数去想。总想着去筛出所有合适的因子然后统计个数,或者直接暴力for去枚举因子(肯定会TLE) 后面想到了一个互质关系(即是已知 \(GCD(X,N) = q\) \(X = q*a\) , \(N=q*b\) \(则a,b必然互质\) ,然后我们就可以找到一个大于M的因子,开心的去找所有满足 小于 b 的互质个数 即可。 然鹅...这不就是欧拉函数吗?所以最后我们在 用一个欧拉函数即可(离线打表和直接算都可以) code: #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <cmath> #define IOS ios :: sync_with_stdio ( 0 ); cin . tie ( 0 ); #define accept 0 #define mp make_pair using namespace std ; typedef long long ll ; typedef unsigned long long ull ; typedef

欧拉函数

匿名 (未验证) 提交于 2019-12-02 23:42:01
\(\varphi(x)\) 表示 \(x\) 以内与 \(x\) 互质的个数 \(\varphi(x)=x*\prod\limits_{i=1}^n(1-\dfrac{1}{p_i})\) \(p_i\) 为x的质因数 特殊的 \(\varphi(1)=1\) 其中 \(p_1,p_2……p_n\) Ϊ \(x\) 的所有质因数( \(x\) 是正整数) 那么,怎么理解这个公式呢? 对于 \(x\) 的一个质因数 \(p_i\) ,因为 \(x\) 以内 \(p_i\) 的倍数是均匀分布的,所以 \(x\) 以内有 \(\frac {1}{p_i}\) 的数是 \(p_i\) 的倍数 对应的,有 \(1-\dfrac {1}{p_i}\) 的数不是 \(p_i\) 同理,对于 \(p_j\) 有 \(1-\frac {1}{p_j}\) 的数不是 \(p_j\) 的倍数 所以有 \((1-\frac {1}{p_i})*(1-\frac {1}{p_j})\) 的数既不是 \(p_i\) 的倍数,又不是 \(p_j\) 的倍数 当有函数 \(f(x)\) , \(m\) 与 \(n\) 互质时, \(f(m)*f(n)=f(m*n)\) 称为积性函数 对任意整数 \(m\) 与 \(n\) , \(f(m)*f(n)=f(m*n)\) 称为完全积性函数 对于质数 \(p\) ,

HDU - 2588 GCD (欧拉函数)

我与影子孤独终老i 提交于 2019-11-28 15:34:50
原题链接 题意: 给你两个数 \(N,M\) 你要求出 符合条件 \(GCD(X,N)>=M,\space (1<=X<=M)\) 中 \(X\) 的个数 思路: 一开始没有往欧拉函数去想。总想着去筛出所有合适的因子然后统计个数,或者直接暴力for去枚举因子(肯定会TLE) 后面想到了一个互质关系(即是已知 \(GCD(X,N) = q\) \(X = q*a\) , \(N=q*b\) \(则a,b必然互质\) ,然后我们就可以找到一个大于M的因子,开心的去找所有满足 小于 b 的互质个数 即可。 然鹅...这不就是欧拉函数吗?所以最后我们在 用一个欧拉函数即可(离线打表和直接算都可以) code: #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <cmath> #define IOS ios::sync_with_stdio(0); cin.tie(0); #define accept 0 #define mp make_pair using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,

BZOJ 2818 欧拉函数,线性筛

烂漫一生 提交于 2019-11-27 13:39:25
题目链接: https://www.acwing.com/problem/content/description/222/ 给定整数N,求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)有多少对。 GCD(x,y)即求x,y的最大公约数。 输入格式 输入一个整数N 输出格式 输出一个整数,表示满足条件的数对数量。 数据范围 1≤N≤10^7 输入样例: 4 输出样例: 4 题解: 首先,用线性筛可以预处理处素数与欧拉函数。 我们定义 count(x)为: 1<=i,j<=N 有多少对gcd(i,j)=x; 那么原问题就转化成 (要求i是素数) 那么问题就转化成了,怎么能快速的求出count(x) 因为 count(x)为:1<=i,j<=N 有多少对gcd(i,j)=x , 那么i和j必须是x的倍数,i和j的范围是x,2x,3x..... *x 那么我们把i和j都约掉一个x,那么约掉后的i和j要求i和j互质,那么问题就转化成: 1<=i,j<= ,有多少对数字两两互质。 那么很容易想到欧拉函数,euler(x) 是 1到x有多少对数字和x互质,然后用前缀和就可以预处出来 sum[1]=1, sum[i]=sum[i-1]+2*euler[i] 代码: #include<bits/stdc++.h> using namespace std; typedef long

day3(数论)

瘦欲@ 提交于 2019-11-27 01:01:51
总 得来说,这是可怕的一天,极其可怕的一天 (完) 一、数论 阴影啊! 首先,设ab为两个整数,则存在唯一的q和r,使得a=qb+r 若r=0,则b整除a,记作b|a。 (1)同余 若a/m和b/m的余数相同,则称a于b对模m同余,记作a ≡ b (mod m) 剩余系:在模 m 的意义下,余数相同的数归为一个集合,那么所有整数被分为 m个不同的集合,模 m 的余数分别为 0,1,2,3,...,m − 1,这些集合被称为模 m 剩余类(同余类)。每个同余类中的任意两个整数都是模 m 同余的。__by dzy(就是模m的余数集合) 若是剩余系遍历了0~m-1,则叫做完全剩余系 同余式的三则运算: 设 a,b,c,d 为整数,m 为正整数,若 a ≡ b (mod m),c ≡ d(mod m),则: ax + cy ≡ bx + dy (mod m),其中 x,y 为任意整数,即同余式可以相加() ac ≡ bd (mod m),即同余式可以相乘a n ≡ b n (mod m),其中 n > 0 f(a) ≡ f(b) (mod m),其中 f(x) 为任一多项式。 a n ≡ b n (mod m),其中 n > 0 (2)素数 判断素数的方法:一般是从2开始,枚举到√ n,依次判断i是否能整除n,若n=pq,则pq中的一个必定小于等于√ n。 但是,如果硬生生跑√ n