中国剩余定理

扩展中国剩余定理(exCRT)

余生颓废 提交于 2020-01-24 19:16:29
我 tm……CRT 没看懂 exCRT 却看懂了……emmmm…… 而且这名字完全就是 国内的 OI 带师 胡起的吧…… 考虑一次同余方程组 \[\begin{cases} x \equiv a_1\ ({\rm mod}\ m_1) \\ x\equiv a_2\ ({\rm mod}\ m_2) \\ ... \\ x \equiv a_n\ ({\rm mod}\ m_n)\end{cases}\] 的解的问题。 CRT 成立的前提是 \(\gcd\{m_n\}=1\) 。这里不一定保证这个条件。 原理还是很简单的,利用归纳法,考虑前 \(k-1\) 个方程组的解为 \(x\) ,并记 \(m={\rm lcm}(m_1,\dots,m_{k-1})\) ,那么对于第 \(k\) 个方程,就是找一个 \(t\in\mathbb{Z}\) ,使得 \(x+tm\equiv a_k\pmod{m_k}\) 。把 \(x\) 扔到右边就是一个 \(tm\equiv a_k-x\pmod{m_k}\) ,可以用 exgcd 求了。 所以纵观整个算法其实是一个不断用 exgcd 迭代的过程。 好,理论说完了,来到 毒瘤 代码环节……这玩意……真心没办法言传……我看了好久才会orz…… 把关键部分注释一下: int main() { scanf("%d",&n); ll M,ans,x

【模板】扩展中国剩余定理(EXCRT)

我的未来我决定 提交于 2020-01-24 10:58:53
一、题目: 洛谷模板 二、代码: #include<iostream> #include<cstdio> #include<cstring> #define LL long long #define mem(s,v) memset(s,v,sizeof(s)) #define FILE(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout) using namespace std; template<class Type> inline Type read(Type num){ Type x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return f*x; } const int maxn=100005; int n; LL ai[maxn],bi[maxn]; inline LL mult(LL a,LL b,LL p){ LL ret=0; for(;b;b>>=1){ if(b&1)ret=(ret+a)%p; a=(a+a)%p; } return ret; } inline LL exgcd(LL

中国剩余定理

余生颓废 提交于 2020-01-22 18:15:37
中国剩余定理-CRT 一.什么是CRT? ​ CRT是用来解决线性同余方程组的求解的算法。它的前提是所有的模数互质就好。同时也是唯一一个以中国开头的算法(作为中国人要好好学呀)。 二.算法流程 ​ 首先从老祖宗的角度出发,他们当时解决的是这样一个问题。(为什么老祖宗这么强Orz) 三人同行七十稀 五树开花廿一枝 七子团圆正半月 除百零五便可知 ​ 这个问题的解答为该诗的最后一句,自己悟吧!不过我们先解决一个较为抽象的小问题。求 \[ x\equiv r_1(mod\;m_1)\\ x\equiv r_2(mod\;m_2)\\ x\equiv r_3(mod\;m_3)\\ \] 的解。 ​ 先记 \(a_1,a_2,a_3\) 为这三个方程各自的一个解使得 \(x=a_1+a_2+a_3\) 可以解出正解。对于这样的加法我们分类讨论。 对于 \(a_1\) 来说,根据同余的同加性,我们必须保证 \(m_1|a_2,m_1|a_3\) ,这样才能有正确的答案。 对于 \(a_2\) 来说,根据同余的同加性,我们必须保证 \(m_2|a_1,m_2|a_3\) 对于 \(a_3\) 来说,根据同余的同加性,我们必须保证 \(m_3|a_1,m_3|a_2\) 由以上三点可知,每一个数 必须保证是其他模数的倍数 ,由于所有的模数都互质所以说直接乘起来除掉这个数对应的模数就好,即令 \[

【知识总结】数论全家桶

人盡茶涼 提交于 2020-01-18 05:25:05
NOI2019 不到一周了,开始总复习 颓废 咯 ~ 一些数论算法以前已经写过了,本文主要用于总结一些杂七杂八的小算法,查缺补漏。 传送门 (说到传送门,Steam 夏日大促 Portal 2 只要 3 CNY 就是一玩起来就 3D 眩晕没法学习) : 【知识总结】线性筛_杜教筛_Min25筛 【知识总结】扩展卢卡斯定理(exLucas) 【知识总结】Miller-Robin和Pollard-Rho(咕 ~ ) 本文将涉及以下内容: 更相减损术、欧几里得算法及扩展欧几里得算法 逆元 中国剩余定理及扩展中国剩余定理 Lucas 定理 本文中所有字母如无特殊说明均默认为正整数。 更相减损术、欧几里得算法及扩展欧几里得算法 更相减损术 首先一个很显然的结论: \[ \gcd(a,b)=\gcd(a,a-b)(a\geq b) \] (证明略,反正看起来很显然就对了 —— 虽然这个显然的结论经常想不到 QAQ ) 于是可以就照着这个一直递归(或者迭代)下去,边界是 \(\gcd(a,0)=a\) 。 欧几里得算法 这就是大家熟悉的 \(\gcd(a,b)=\gcd(a \bmod b, b)\) ,可以从上面那个结论推过来。同样可以通过递归的方式计算: int gcd(const int a, const int b) { return b ? gcd(b, a % b) : a; }

中国剩余定理

邮差的信 提交于 2020-01-17 05:27:05
https://www.cnblogs.com/MashiroSky/p/5918158.html (拼凑自以上连接) 备忘录: a|b是指a能整除b,a是b的因式,4|2是不成立的,2|4才成立 lcm(a,b) 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 x1 = y,y1 = x-a/b*y; x = x1; y = y1; return g; } int inv(int m, int p){ int x, y; int g = exgcd(m,p,x,y); return ((x%p)+p)%p; } ll CRT(ll a[], ll m[], int n) { ll M=1; for(ll i=0; i<n; i++) M*=m[i]; ll ans=0; for(ll i=0; i<n; i++){ ll Mi=M/m[i]; ll x=inv(Mi,m[i]); ans=(ans+Mi*x*a[i])%M; } return (ans+M)%M; } 扩展 中国剩余定理

模板—中国剩余定理+拓展GCD

隐身守侯 提交于 2020-01-14 13:22:15
1 int exgcd(int a,int b,int &x,int &y) 2 { 3 if(b==0) 4 { 5 x=1,y=0; 6 return a; 7 } 8 int gcd=exgcd(b,a%b,x,y); 9 int t=x; 10 x=y; 11 y=t-a/b*y; 12 return gcd; 13 } 14 int China(int W[],int B[],int k) 15 { 16 int x,y,a=0,m,n=1; 17 for(int i=1;i<=k;i++) 18 n*=W[i]; 19 for(int i=1;i<=k;i++) 20 { 21 m=n/W[i]; 22 exgcd(W[i],m,x,y); 23 a=(a+y*m*B[i])%n; 24 } 25 return a>0?a:(a+n); 26 } 不知道为啥,用快速幂求逆元就挂了… 来源: https://www.cnblogs.com/Al-Ca/p/11101929.html

扩展中国剩余定理详解

亡梦爱人 提交于 2020-01-13 12:07:29
前言 阅读本文前,推荐先学一下中国剩余定理。其实不学也无所谓,毕竟两者没啥关系 扩展CRT 我们知道,中国剩余定理是用来解同余方程组 $$\begin{cases}x\equiv c_{1}\left( mod\ m_{1}\right) \\ x\equiv c_{2}\left( mod\ m_{2}\right) \\ \ldots \\ x\equiv c_r\left( mod\ m_r\right) \end{cases}$$ 但是有一个非常令人不爽的事情就是它要求$m_1,m_2\ldots,m_r$两两互素 如果某个毒瘤出题人偏要求它们部互素呢? 其实也有解决的办法 就是 把出题人吊起来干一顿 用扩展中国剩余定理 扩展中国剩余定理跟中国剩余定理没半毛钱关系,一个是用扩展欧几里得,一个是用构造 首先我们还是从简单入手,考虑一下如果同余方程组只有两个式子的情况 $x\equiv c_{1}\left( mod\ m_{1}\right) \\ x\equiv c_{2}\left( mod\ m_{2}\right)$ 将两个式子变形 $x=c_{1}+m_{1}k_{1}\\ x=c_{2}+m_{2}k_{2}$ 联立 $c_{1}+m_{1}k_{1}=c_{2}+m_{2}k_{2}$ 移项 $m_{1}k_{1}=c_{2}-c_{1}+m_{2}k_{2}$

扩展中国剩余定理

女生的网名这么多〃 提交于 2020-01-13 04:11:34
若有以下两个同余方程 x ≡ a1 mod n1 x ≡ a2 mod n2 x= n1*k1+a1 = n2*k2+a2 ∴ n1*k1 = n2*k2+a2-a1 ∴ n1*k1 ≡ a2-a1 mod n2 由扩展欧几里得定理得,同余方程有解的条件是 gcd(n1,n2) | (a2-a1) 令d=gcd(n1,n2),c=a2-a1 则n1/d * k1 ≡ c/d mod n2/d ∴ k1 = c/d * inv(n1/d)mod n2/d 令k=c/d * inv(n1/d),则k1 = k + (n2/d)*y ∴ x=n1*(k + (n2/d)*y)+a1 =(n1*n2/d)*y+n1*k+a1 即 x ≡ n1*k+a1 mod n1*n2/d 所以上面两个方程合并为 x ≡ a mod n 其中 a=n1*k+a1 n=n1*n2/d #include<cstdio> #include<iostream> using namespace std; typedef long long LL; int n[11],a[11]; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar

中国剩余定理

♀尐吖头ヾ 提交于 2020-01-10 19:03:25
前言: 中国剩余定理($CRT$),也称 孙子定理 ,原文如下: “有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?” 很明显这是一个同余方程组,于是我们就可以用中国剩余定理求解 正文: 中国剩余定理 中国剩余定理适用于求解模数两两互质时的同余方程组 设 $b_1,b_2,\ldots,b_n$ 两两互质 则同余方程组 $\begin{cases} x\equiv a_1\ (mod\ b_1) \\ x\equiv a_2\ (mod\ b_2) \\ \qquad\dots \\ x\equiv a_n\ (mod\ b_n) \end{cases}$ 有整数解 并且在 $mod\ lcm=\prod_{i=1}^{n}b_i$ 意义下有唯一解 为 $x=\sum_{i=1}^ka_i*left*inv\;\%\;lcm$ 其中 $left=\dfrac{lcm}{b_i}$ ,$inv$ 为 $left\ mod\ b_i$ 意义下的逆元 同时 $CRT$ 一般会配合 龟速乘 ,防止乘起来会爆 $long\ long$ void exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1,y=0; return; } exgcd(b,a%b,y,x); y-=a/b*x; } ll qmul(ll a,ll b,ll p) {

中国剩余定理与扩展中国剩余定理

泪湿孤枕 提交于 2020-01-10 03:29:26
中国剩余定理与扩展中国剩余定理 概述 中国剩余定理是同余中常用的辅助手段,常用来合并多个同余方程的解(如MTT)。其技术难度不高,代码也很短,可以在NOIP中出现。 中国剩余定理CRT 形式 给定 \(n\) 组非负整数 \(m_i, a_i\) ,求解关于 \(x\) 的方程组的最小非负整数解。 \[\begin{cases} x \equiv a_1\ ({\rm mod}\ m_1) \\ x\equiv a_2\ ({\rm mod}\ m_2) \\ ... \\ x \equiv a_n\ ({\rm mod}\ m_n)\end{cases}\] 其中 \(m_i\) 两两互质。 解法 我们贪心构造和式使得每一项在模意义下不影响其他项,并且符合当前的方程, 设 \(M =\prod^{n}_{i=1}m_i,M_i=\frac{M}{m_i}\) ,可以构造解 \[x=\sum^{n}_{i=1}M_i(a_iM_i^{-1} \mod m_i)\] 可以证明解在模M 意义下唯一。 模板题: P3868 [TJOI2009]猜数字 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int INF=1e9+7,MAXN=11; inline LL mult(LL a,LL b