数论

『数论』求最大公因数

安稳与你 提交于 2019-12-01 18:28:56
//#define fre yes #include <cstdio> int gcd(int a, int b) { if(b != 0) gcd(b, a % b); else return a; } 谈论数论不废话 ----- 辗转相除法求gcd 以上代码的时间复杂度为 \(O(\log n)\) 证明,为何 \(gcd(b, a \mod b) = gcd(a, b)\) 设 \(g = gcd(a, b)\) 那么一定有 \(a = xg , b = yg\) 我们又可以将 a 用 b 来表示,(任何数都可以用另外一个数表示) \(a = kb + r\) ( \(k\) 为 \(a / b\) 的整数部分, \(r\) 为 \(a / b\) 的余数部分 也就是 \(a \mod b\) ),转化一下 \(r = a - kb\) 那么将上面的 a, b 代入,也就变成了 \(r = xg - kyg = (x - ky)g\) 此时的 g 也是 r 的因数了,又因为 \(r\) 为 \(a \mod b\) 所以 \(gcd(a, b) = gcd(b, a \mod b)\) 证毕 来源: https://www.cnblogs.com/Nicoppa/p/11712072.html

『数论』线性筛质数

ε祈祈猫儿з 提交于 2019-12-01 18:25:16
//#define fre yes #include <cstdio> const int N = 100005; int prime[N], isNotprime[N]; void isprime(int n) { int cnt = 0; isNotprime[1] = 1; for (int i = 2; i <= n; i++) { if(!isNotprime[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { isNotprime[i * prime[j]] = 1; if(i % prime[j] == 0) break; } } } 谈论数论不废话 ----- 线性筛 以上代码的时间复杂度是 \(O(n)\) 需要注意以下几点 1为素数,不为质数 如果当前不是素数,那么一定是质数(显然可得) 第二层循环中 为什么是 \(i \times prime[j] <= n\) 因为循环内用到了这个乘 最重要的是最后一句 \(i \mod prime[j] == 0\) 这句话是什么意思 我们可以假设没有这句话,那么当发生 \(i\mod prime[j] == 0\) 的时候,我们就知道 这个 \(i\) 必定包含 \(prime[j]\) 这样也就说明了此时 \(i\) 是

数论【1】

浪尽此生 提交于 2019-12-01 12:08:27
这是数论专区的第一部分,同时也是最简单的一部分。 Part 1:符号表示&约定 以下是可能用到的符号: $\max(a,b)$:$a$ 与 $b$ 的较大值 $\min(a,b)$:$a$ 与 $b$ 的较小值 $\lfloor a \rfloor$:实数 $a$ 下取整的值 $\lceil a \rceil$:实数 $a$ 上取整的值 $\mid a \mid$:数 $a$ 的绝对值 $a \mid b$ :数 $b$ 被 $a$ 整除 $a \nmid b$:数 $b$ 不被 $a$ 整除 $a ≡ b$ $(\text{mod } c)$ :$a$ 与 $b$ 模 $c$ 同余 $gcd(a,b)$:数 $a$ 和数 $b$ 的最大公约数 $lcm(a,b)$:数 $a$ 和数 $b$ 的最小公倍数 $a$ $!$ : 数 $a$ 的阶乘的值 约定: $\overline{abc}$ 表示一个三位整数,$a,b,c$ 分别代表百位,十位,个位的数值。 不特殊说明的情况下,数字默认为十进制整数。 Part 2:整除 从易到难。 ① 说明某个位数之和是 $3$ 倍数的数一定能被 $3$ 整除。 分析:   有一个简单的结论:若 $k \mid a$,$k \mid b$,那么 $k \mid a + b$,此处不详细说明。   我们从任意三位数 $\overline{abc}$

扩展欧几里德算法(数论)

元气小坏坏 提交于 2019-12-01 10:16:38
根据贝祖定理:如果a、b是整数,那么一定存在整数x、y使得ax+by=gcd(a,b)。扩展欧几里德定理的作用就是不仅求出了最小公倍数,还能求出一组解x,y(x,y可能为负数),使得 ax + by = gcd(a,b)#include<bits/stdc++.h> #define llinf (0x3f3f3f3f3f3f3f3f) #define inf (0x3f3f3f3f) typedef long long i64; using namespace std; i64 exgcd(i64 a,i64 b,i64& x,i64& y) { if(b == 0) { x = 1,y = 0; return a; } i64 r = exgcd(b,a%b,x,y); i64 tmp = y; y = x - (a/b)*y; x = tmp; return r; } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); i64 a,b; cin>>a>>b; i64 r = exgcd(a,b,x,y); cout<<x<<" "<<y<<'\n'; }    https://blog.csdn.net/destiny1507/article/details/81750874 来源: https:/

逆元(数论倒数)【密码学笔记】

本小妞迷上赌 提交于 2019-12-01 07:05:57
数论倒数,又称逆元 取模 对于取模,有一下一些性质: 但是唯独除法是不满足的: 为什么除法错的呢?很好证明: 而对于一些题目,我们必须在中间过程中进行求余,否则数字太大,电脑存不下,那如果这个算式中出现除法,我们就需要逆元了。 逆元 定义: 我们知道,如果a*x = 1,那么x是a的倒数,x = 1/a 而在数论问题中,大部分情况都有取模,所以问题就变成了: 那么x就不一定等于1/a了 所以这时候,我们就把x理解为在模p空间下,a的倒数,满足: 现在就要在回到刚才的问题了,除以一个数等于乘上这个数的倒数,在除法取余的情况下,就是乘上这个数的逆元,即: 这样就把除法,完全转换为乘法了。 逆元的求解 对于逆元的求解,如果n较小的话,是容易算出来的,例如,求3在模26下的逆元: 但是当n非常大的时候,就需要引入一个算法来计算 (1)扩展欧几里得算法(extend_gcd) 对于逆元的表达式可以做一些变换: 当gcd(a,n)=1时,代入extend_gcd(a,b,x,y),得到的非负的x值,就是a对模n的逆元。 算法实现与证明 也就是说,我们得到了一个和gcd算法中,gcd(m,n)=gcd(n,m%n)相似的恒等式 什么意思呢?举个例子,就是 如果想要x为正值 只再做一步: if (x < 0) { x += b; y -= a; } 扩展: 完整算法: int extend_gcd

数论---lcm和gcd

邮差的信 提交于 2019-12-01 02:10:41
cd即最大公约数,lcm即最小公倍数。 首先给出a×b=gcd×lcm 证明:令gcd(a,b)=k,a=xk,b=yk,则a×b=x y k k,而lcm=x y k,所以a b=gcd*lcm。 所以求lcm可以先求gcd,而求gcd的方法就是辗转相除法,也叫做欧几里德算法,核心为gcd(m,n)=gcd(n,m%n) 递归实现: ''' LL gcd(LL a, LL b){ return b ? gcd(b, a%b) : a; } ''' while循环: ''' LL gcd(LL a, LL b){ LL t; while(b){ t = b; b = a % b; a = t; } return a; } ''' 来源: https://www.cnblogs.com/ACMerLwy/p/11647373.html

【数论】P2312解方程

∥☆過路亽.° 提交于 2019-11-30 19:06:17
【数论】P2312解方程 题目描述 已知多项式方程: \(a_0 + a_1x + a_2x^2+...+a_nx^n = 0\) 求这个方程在[1,m]内的整数解 \(1\leq n\leq100,|a_i|\leq 10^{10000},a_n≠0,m\leq 10^6\) Solution 首先由于数据过大,只能字符串读入了hhh。然后:对于每个x,算出f(x)%pi,如果f(x)=0则f(x)%pi必然=0,多选几个素数,就可以在一定范围大小内判断成功。好像不够快? \(f(x+p)≡f(x)(mod p)\) 对于一个x, \(f(x)≠0(mod p)\) ,则x+p,x+2p……均不为方程的解 有了这个性质就可以瞎搞了。取几个较大的质数搞一搞…… Code #include <iostream> #include <cstdio> using namespace std; inline long long read() { long long x = 0; int f = 0; char c = getchar(); while (c < '0' || c > '9') f |= c == '-', c = getchar(); while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c =

day 5 【B班】wqy数论进阶

断了今生、忘了曾经 提交于 2019-11-30 18:20:15
费马小定理、欧拉定理与扩展欧拉定理 证明 Miller_Rabin素数测试 int prime[10]={2,3,5,7,11,13,17,19,23,29}; inline int ksc(int a,int k,int mod){ int res=0; for(;k;k>>=1){ if(k&1) res=(res+a)%mod; a=(a+a)%mod; } return res; } inline int ksm(int a,int k,int mod){ int res=1; for(;k;k>>=1){ if(k&1) res=ksc(res,a,mod); a=ksc(a,a,mod); } return res; } inline bool Miller_Rabin(int n){ int q=0,p1=n-1;//将n=2^q+p1; if(n==2)return 1;//特判0,1,2,偶数(因为接下来的只适用于素数) if(n<2 || !(n&1))return 0; while(!(p1&1)){//p1不为2就一直分解 q++; p1>>=1; } int now; for(int i=0;i<10 && prime[i]<n;++i){//测试质数 int a=prime[i]; int last=ksm(a,p1,n);//从a^p1开始测 rep

洛谷$P4884$ 多少个1? 数论

旧时模样 提交于 2019-11-30 13:24:39
正解:$BSGS$ 解题报告: 传送门$QwQ$ 首先看到这个若干个一,发现不好表示,考虑两遍同时乘九加一,于是变成$10^n\equiv 9\cdot K+1(mod\ m)$ 昂然后不就是$bsgs$板子了嘛?太板子了不说了$kk$ $over$ 来源: https://www.cnblogs.com/lqsukida/p/11575575.html