gcd

你也可以手绘二维码(二)纠错码字算法:数论基础及伽罗瓦域GF(2^8)

自作多情 提交于 2020-02-28 11:34:47
摘要:本文讲解二维码纠错码字生成使用到的数学数论基础知识,伽罗瓦域(Galois Field)GF(2^8),这是手绘二维码填格子理论基础,不想深究可以直接跳过。同时数论基础也是 Hash 算法,RSA 算法等密码学的入门基础。 二维码生成算法最为核心的就是编码规则和纠错码字的生成。本篇专门讲解纠错涉及到的伽罗瓦域(Galois Field)。本文内容大部分是阅读《密码编码学与网络安全》后参考相关 PPT 编写,如有遗漏或不严谨地方请参考专业书籍。 数论基础 整除,因数,素数 设 a , b(b≠0) 是两个整数,如果存在另外一个整数 c 使得 a=b·c , 则称 b 整除 a, 记为 b|a, 且称 b 为 a 的因子。如果 p (p>1) 的因子只有 ±1,±p,称整数 p 是素数。 模 如果 a 和 n(n≠0) 是两个整数,则定义 a mod n 是 a 除以 n 所得的余数。正整数 n 称为模数。因此对于任意整数 a 可以写出: a = qn + r (0<=r<n);q= ⌊a/n⌋ a = ⌊a/n⌋ * n + ( a mod n) 例子: a = 49,n = 8, 则 q = 49 mod 8 = floor(49/8) = 6 , r = 49 mod 8 = 1 ,49 = 6 * 8 + 1 . 最大公因数 最大公因数,也称最大公约数、最大公因子

求最大公约数(GCD)的两种算法

拜拜、爱过 提交于 2020-02-28 11:24:07
之前一直只知道欧几里得辗转相除法,今天学习了一下另外一种、在处理大数时更优秀的算法——Stein 特此记载 1.欧几里得(Euclid)算法 又称辗转相除法,依据定理gcd(a,b)=gcd(b,a%b) 实现过程演示: sample:gcd(15,10)=gcd(10,5)=gcd(5,0)=5 C语言实现: 1 int Euclid_GCD(int a, int b) 2 { 3 return b?Euclid_GCD(b, a%b):a; 4 } 2.Stein 算法 一般实际应用中的整数很少会超过64位(当然现在已经允许128位了),对于这样的整数,计算两个数之间的模是很简单的。对于字长为32位的平台,计算两个不超过32位的整数的模,只需要一个指令周期,而计算64位以下的整数模,也不过几个周期而已。但是对于更大的素数,这样的计算过程就不得不由用户来设计,为了计算两个超过 64位的整数的模,用户也许不得不采用类似于多位数除法手算过程中的试商法,这个过程不但复杂,而且消耗了很多CPU时间。对于现代密码算法,要求计算 128位以上的素数的情况比比皆是,设计这样的程序迫切希望能够抛弃除法和取模。 依据定理: gcd(a,a)=a,也就是一个数和其自身的公约数仍是其自身。 gcd(ka,kb)=k*gcd(a,b),也就是 最大公约数 运算和倍乘运算可以交换。特殊地,当k=2时

扩展欧几里得算法详解

对着背影说爱祢 提交于 2020-02-28 11:22:39
一:欧几里得算法(辗转相除法) 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)。 证明: a可以表示成a = kb + r,则r = a mod b   假设d是a,b的一个公约数,则有   d|a, d|b,而r = a - kb,因此d|r   因此d是(b,a mod b)的公约数   假设d 是(b,a mod b)的公约数,则   d | b , d |r ,但是a = kb +r   因此d也是(a,b)的公约数   因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证 算法实现: int gcd( int a, int b) { //递归算法 return b ? gcd(b, a%b) : a; } int Gcd(inta, int b) { //迭代算法 while(b != 0) { int r = b; b = a%b; a = r; } return a; } 二 扩展欧几里得算法: 基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。 证明:设 a>b。   1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;   2,ab!

GCD串行,GCD并行,GCD同步与异步,

随声附和 提交于 2020-02-25 03:34:44
1. GCD 简介   什么是 GCD 呢???   哈哈,啰嗦一下,想直接看代码的可以直接看第4条   答曰:Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。 它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并发任务。 在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用。   GCD是一个替代诸如NSThread等技术的很高效和强大的技术。GCD完全可以处理诸如数据锁定和资源泄漏等复杂的异步编程问题。 GCD的工作原理是让一个程序,根据可用的处理资源,安排他们在任何可用的处理器核心上平行排队执行特定的任务。这个任务可以是 一个功能或者一个程序段。 ↑ 来自百科( 我是百科链接 ) 好吧,但他有什么用呢? GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程) 程序员只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码 GCD 可用于多核的并行运算 等    2. GCD 任务和队列 GCD两个核心的概念:任务和队列 任务:    就是执行操作的意思,就是你在线程中执行的那段代码,在 GCD 中是放在 block 中的。   执行任务有两种方式:同步执行(sync)和异步执行(async)。   两者的主要区别是

GCD同步异步 串行并行大解析

倖福魔咒の 提交于 2020-02-25 03:33:34
/** 核心概念 任务:block里需要执行的操作 队列:把任务添加进入队列中,按照先进先出的原则来执行任务 串行队列:一个一个的执行 并行队列:可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)并发功能只有在异步(dispatch_async)函数下才有效。 同步任务:不会开辟新的线程,任务在当前的线程中执行,同时任务是立刻执行 异步任务:会开辟新的线程(主队列不可以),任务在新开辟的线程执行(主队列在主线程中执行),不是立刻 执行任务 同步任务串行队列:不会开启新的线程,当前的线程中顺序执行任务 同步任务并行队列:不会开启新的线程,当前的线程中执行任务,立刻执行任务 异步任务串行队列:会开辟一个新的线程,在新开辟的线程中执行任务,不是立刻执行 异步任务并行队列:会开辟新的线程,在新开辟的线程中执行任务,任务的完成顺序是无序的,不是立刻执行 主队列(特殊的串行队列):任务只会在主线程中调度,不会开辟新的线程(一般用于刷新UI) 异步任务主队列:不会开辟新的线程,当前的线程中执行任务,不会立刻执行任务 同步任务主队列:死锁 全局队列(并行队列):全局队列供给应用程序共享,可以设置优先级 开辟新的线程:由任务决定,同步任务不会开辟新的线程,异步任务会开辟新的线程(主队列不会开辟新的线程) 开辟多少线程:由队列决定,串行队列只会开启一个线程,并行队列会开辟多个线程

UVA1642:Magical GCD

╄→尐↘猪︶ㄣ 提交于 2020-02-14 06:37:33
UVA1642:Magical GCD 题意: 给定一个长度为 \(n\leq 10^5\) ,每个数 \(a_i\leq10^{12}\) ,找一个连续子序列使得子序列的公约数与长度的乘积最大。 \(T\) 组数据。 思路: 区间最大公约数模板题。 枚举 \((i,j)\) 暴力的话时间复杂度为 \(O(n^2logn)\) ,肯定会超时的。 给定序列 \(a\) ,连续子段的 \(gcd\) 有 \(log(max\{a_i\})\) 种可能。 \(gcd(1,..,i)=gcd(gcd(1,..,i-1),a(i))\) 。 所以每次固定右端点,向左寻找不同 \(gcd\) 的取值。 #include<bits/stdc++.h> #define PLI pair<long long, int> using namespace std; typedef long long ll; const int maxn = 1e5+10; ll a[maxn]; int n; ll gcd(ll a, ll b) { if(b == 0) return a; return gcd(b, a%b); } //fir->gcd sec->右端点索引 vector<PLI> g[maxn]; void solve() { scanf("%d", &n); for(int i = 1; i <

洛谷 P1072 Hankson 的趣味题

狂风中的少年 提交于 2020-02-13 20:02:43
       洛谷 P1072 Hankson 的趣味题 题目描述 H a n k s 博士是 B T ( B i o − T e c h ,生物技术) 领域的知名专家,他的儿子名叫 H a n k s o n 。现在,刚刚放学回家的 H a n k s o n 正在思考一个有趣的问题。 今天在课堂上,老师讲解了如何求两个正整数 c 1 ​ 和 c 2 ​ 的最大公约数和最小公倍数。现在 H a n k s o n 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数 a 0 ​ , a 1 ​ , b 0 ​ , b 1 ​ ,设某未知正整数 x 满足: 1. x 和 a 0 ​ 的最大公约数是 a 1 ​ ; 2. x 和 b 0 ​ 的最小公倍数是 b 1 ​ 。 Hankson 的“逆问题”就是求出满足条件的正整数 x 。但稍加思索之后,他发现这样的 x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮助他编程求解这个问题。 输入输出格式 输入格式: 第一行为一个正整数 n ,表示有 n 组输入数据。接下来的 n 行每行一组输入数据,为四个正整数 a 0 ​ , a 1 ​ , b 0 ​ , b 1 ​ ,每两个整数之间用一个空格隔开。输入数据保证 a 0 ​ 能被

GCD实现多个定时器,完美避过NSTimer的三大缺陷(RunLoop、Thread、Leaks)

落花浮王杯 提交于 2020-02-11 01:04:39
定时器在我们每个人做的iOS项目里面必不可少,如登录页面倒计时、支付期限倒计时等等,一般来说使用NSTimer创建定时器: + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo; + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo; But 使用NSTimer需要注意一下几点: 1、必须保证有一个活跃的RunLoop。 系统框架提供了几种创建NSTimer的方法,其中以scheduled开头的方法会自动把timer加入当前RunLoop,到了设定时间就会触发selector方法,而没有scheduled开头的方法则需要手动添加timer到一个RunLoop中才会有效。程序启动时,会默认启动主线程的RunLoop并在程序运行期内有效

poj1061 青蛙的约会(扩欧)

走远了吗. 提交于 2020-02-10 15:33:03
记得以前就写过这道题,但死活wa......这几天重新看了一下exgcd,做了noip2012的d2t1和这道。 exgcd用引用记录x,y的值 然后做poj1061的时候,发现仿佛ax=k(mod m) 这儿的a系数得是正的?如果a<0就把两边同乘-1,再用exgcd出x的特解 求出特解x0之后一切都好办了,可以很方便求出最小非负整数解(x0%(m/gcd(a,m))+m/gcd(a,m))%(m/gcd(a,m))或者以m/gcd(a,m)为周期可以求出满足某些条件的解。 (btw,ax+by=c同理,求出一个特解x0*(c/gcd)之后,可以求出同上的最小非负整数解,也可以b/gcd(a,b)为周期求出满足题目条件的解,通解为x=x0*(c/gcd)+(b/gcd)*k,k为任意整数) 上个代码 include<iostream> using namespace std; #define ll long long ll g,x,y,m,n,l,x0,p,q,c,a; ll exgcd(ll a,ll b, ll&x,ll&y) { int t,g; if (b==0){x=1;y=0;return a;} g=exgcd(b,a%b,x,y); t=x;x=y;y=t-(a/b)*y; return g; } void solve() { if (m==n) {cout<<