中国剩余定理

中国剩余定理及其扩展

匿名 (未验证) 提交于 2019-12-03 00:43:02
m 1 , m 2 , m 3 m n m 1 , m 2 , m 3 m n 两两互素,有同余方程组: x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) x ≡ a n ( m o d m n ) { x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) x ≡ a n ( m o d m n ) 求最小的满足方程的 x x 。 由于网上对中国剩余定理的基本概念讲述的差不多了,这里就直接进入正题。 为了方便后面的描述,我们定义 M = ∏ i = 1 n m i , w i = M m i M = ∏ i = 1 n m i , w i = M m i (这个定义不用于后面的扩展中国剩余定理和其它情况)。 我们的目的是想对于每一个方程找出一个比较特殊的 p i p i ,使得 p i ≡ a i m o d m i p i ≡ a i m o d m i ,且 p i ≡ 0 m o d m j ( j ≠ i ) p i ≡ 0 m o d m j ( j ≠ i ) ,因为求出所有的 p i p i 后, ∑ i = 1 n p i m o d M ∑ i = 1 n p i m o d M 就是我们的答案 x x 。 观察 p i p i 的限制,可以发现 p i p i 应该为除了 m i m i

【洛谷P2480】古代猪文

匿名 (未验证) 提交于 2019-12-03 00:14:01
题目大意:求 \[ G^{\sum\limits_{d|N}\binom{n}{k}} mod\ \ 999911659 \] 题解:卢卡斯定理+中国剩余定理 利用卢卡斯定理求出指数和式对各个素模数的解,再利用中国剩余定理合并四个解即可。 也可以在枚举 N 的因子的过程中,对于计算的四个解直接进行中国剩余定理的合并,答案不变。 代码如下 #include <bits/stdc++.h> using namespace std; typedef long long LL; const LL mod = 999911658; const LL md[] = {2, 3, 4679, 35617}; const int maxn = 40000; LL fac[maxn]; inline LL fpow(LL a, LL b, LL c) { LL ret = 1 % c; for (; b; b >>= 1, a = a * a % c) { if (b & 1) { ret = ret * a % c; } } return ret; } inline LL comb(LL x, LL y, LL p) { if (y > x) { return 0; } return fac[x] * fpow(fac[x - y], p - 2, p) % p * fpow(fac[y], p

题解 P1495 【曹冲养猪】

匿名 (未验证) 提交于 2019-12-02 23:57:01
无良宣传一下博客wwwwww 文章列表 - 核融合炉心 - 洛谷博客 现有两组数字,每组 \(k\) 个, 第一组中的数字分别为: \(a_1,a_2,...,a_k\) 表示, 第二组中的数字分别用 \(b_1,b_2, ... ,b_k\) 表示。 第二组中的数字 \(\underline\text{两两互质}\) 。 求最小的非负整数 \(n\) , \(\underline{\text{满足对于任意的}i,n - a_i \text{ 能被 } b_i \text{ 整除}}\) 。 根据题意 , 题干可以转化为: \(\begin{cases}x \equiv a_1\pmod {b_1}\\x \equiv a_2\pmod {b_2}\\......\\x \equiv a_n\pmod {b_n}\\\end{cases}\) 因为 \(bi\) 之间 两两互质 ,所以可以用 中国剩余定理 求解 但是 中国剩余定理 适用范围太小, 这里介绍用 扩展中国剩余定理 求解。 一道模板题: P4777 【模板】扩展中国剩余定理(EXCRT) \(\begin{cases}x \equiv a_1\pmod {b_1}\\x \equiv a_2\pmod {b_2}\\......\\x \equiv a_n\pmod {b_n}\\\end{cases}\) 其中 , \

模板 - 扩展中国剩余定理

匿名 (未验证) 提交于 2019-12-02 23:55:01
解k个线性同余方程构成的线性同余方程组,每个方程形如: $x_i = c_i mod m_i$ ,假如有解输出最小非负整数解,否则输出-1。 可能在模数比较大的时候会溢出的版本,方法是直接对两个方程强行合并。 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXK = 100005; void exgcd(ll a, ll b, ll &x, ll &y) { if(!b) x = 1, y = 0; else exgcd(b, a % b, y, x), y -= a / b * x; } ll inv(ll a, ll b) { ll x = 0, y = 0; exgcd(a, b, x, y); x = (x % b + b) % b; if(!x) x += b; return x; } int k; ll c[MAXK], m[MAXK]; //解k个线性同余方程构成的方程组, xi = ci mod mi ,假如有解,返回最小非负整数解,否则返回-1 ll exCRT(int k) { ll c1, c2, m1, m2, t; for(int i = 2; i <= k; ++i) { m1 = m[i - 1], m2 = m[i], c1 = c[i -

拓展中国剩余定理(excrt)

匿名 (未验证) 提交于 2019-12-02 23:51:01
问题 求解同余方程组 其中各个方程的模数 为不一定两两互质的整数, 求x的最小非负整数解 求解 假设已经求出前k-1个方程组成的同余方程组的一个解为x 且有 M=lcm(mo[1],mo[2],mo[3],...,mo[k-1]) 则前k-1个方程的方程组通解为 因为M为前面方程模数的最小公倍数,所以M可以整除任意一个模数,所以方程组加上或减去M对于方程的同余性没有影响。 那么对于加入第k个方程后的方程组 x + t M ≡yu[ k] ( mod mo[k] ) t M ≡yu[k] x ( mo[k] ) 对于这个式子我们已经可以通过扩展欧几里得求解t 若该同余式无解,则整个方程组无解, 若有,则前k个同余式组成的方程组的一个解解为 x k =x+t*M 所以整个算法的思路就是求解k次扩展欧几里得 洛谷 P4777 #include<bits/stdc++.h> using namespace std; #define ll __int128 ll ans,x,y,a,b,c,yu[100005],mo[100005],M,n; long long read()//int 128好像只能用快读 { ll f=1,x=0; char ss=getchar(); while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();} while

中国剩余定理 CRT

匿名 (未验证) 提交于 2019-12-02 23:49:02
1. 一条数学公式: 如果有 a%b=c, 则有 (a+kb)%b=c(k 为非零整数) 2. 用途:求解一次线性同余方程组 ,需要将模数转化为素数来求解的题目 3. ( N / m i ) y i ≡ 1 ( m o d m i y i ( N / m 1 ) + q m 1 = 1 (若mi互质,1 = g c d ( N / m 1 , m 1 )) //hoho,前面一大堆乱七八糟的困得时候写的,重新来 前提: mi两两互质 --》可推出任意ai方程组都有解 假设: 求解: 所以方程组的通解形式为 x=a1t1M1+a2t2M2+...+antnMn+kM, k∈Z 在模M的意义下,方程组只有一个解 x=(a1t1M1+a2t2M2+...+antnMn)mod M ①求基础数的方法:(1) while自增,用其他数的最小公倍数不断自增,直到余数满足条件          (2) 辗转相除法,联系乘法逆元。 证明: j 除此之外,参考百科(真的看不懂了 orz ▲ 联系孙子算法 的那题,就是:已知m1,m2,m3是两两互质的正整数,求最小的正整数x,使它被m1,m2,m3除所得的余数分别是c1,c2,c3。 (1) 先求出Mi 即不被mi整除,但被其他两个数整除的数 (3) 这么搞则得到满足题意的数c1M1+c2M2+c3M3,但它不一定最小,如果比lcm小的话减一下就好。

中国剩余定理(费马小定理求逆元)

匿名 (未验证) 提交于 2019-12-02 23:43:01
1079 中国剩余定理 1.0 秒 131,072.0 KB 0 分 基础题 一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K。例如,K % 2 = 1, K % 3 = 2, K % 5 = 3。符合条件的最小的K = 23。 输入 第1行:1个数N表示后面输入的质数及模的数量。(2 <= N <= 10) 第2 - N + 1行,每行2个数P和M,中间用空格分隔,P是质数,M是K % P的结果。(2 <= P <= 100, 0 <= K < P) 输出 输出符合条件的最小的K。数据中所有K均小于10^9。 输入样例 3 2 1 3 2 5 3 输出样例 23代码 #include<cstdio> #include<iostream> using namespace std; #define ll long long ll a[20],p[20],b[20]; ll power(ll x,ll p1) { ll b=p1-2,sum=1; while(b) { if(b&1) sum=(sum*x)%p1; x=(x*x)%p1; b=b>>1; } return sum; } int main() { ll n,M=1,sum=0; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]>>p[i]; M=M*a[i]; }

数论四大定理

匿名 (未验证) 提交于 2019-12-02 22:56:40
1.威尔逊定理: 当且仅当p为素数时:( p -1 )! ≡ p-1 ( mod p ) 即若p为质数,则p能被(p-1)!+1整除 2.欧拉定理: 欧拉定理:也称费马-欧拉定理 若n,a为正整数,且n,a互质,即gcd(a,n) = 1,则a^φ(n) ≡ 1 (mod n) φ(n) 是欧拉函数: 如果n是质数,那么1到n-1所有数都是与n互质的,所以φ(n) = n-1 欧拉公式: e的ix次方 = cosx + isinx 把x用π带进去,变成 e的iπ次方= -1 3.孙子定理(中国剩余定理) 用现代数学的语言来说明的话,中国剩余定理给出了以下的一元线性同余方程组: 中国剩余定理说明:假设整数 m 1, m 2, ... , m n两两互质,则对任意的整数: a 1, a 2, ... , a n,方程组 (S)有解 4.费马小定理: 假如p是质数,若p不能整除a,则 a^(p-1) ≡1(mod p),若p能整除a,则a^(p-1) ≡0(mod p)。 或者说,若p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1 参考自: http://www.cnblogs.com/linyujun/p/5194142.html 文章来源: 数论四大定理

中国剩余定理和拓展中国剩余定理

一曲冷凌霜 提交于 2019-12-02 19:38:32
拓展和非拓展的中国剩余定理的区别在于同余方程组的mod是否两两互质,没有本质区别(个鬼)。 首先用拓展中国剩余定理是完全可以ac中国剩余定理的板题的,但是性能上会差很多,不过应该不会卡这个常数的吧(大雾) 中国剩余定理是很简单的,用拓展欧几里得的板子,加上下面的原理: 很容易出代码,在这里不写了,您可以参见我的一篇叫《求逆元》的博客,里面有详细的介绍。下面讲讲拓展中国剩余定理的原理,证明很简单但是很长,所以只放一个引理。 然后我们就可以把两个方程化成一个。方程越化越少,最后化成一个的时候就胜利了。 出一个拓展中国剩余定理的板子。 1 #include<bits/stdc++.h> 2 #define ll long long 3 #define scan(i) scanf("%lld",&i) 4 using namespace std; 5 const int maxn=100010; 6 int n; 7 ll ai[maxn],bi[maxn]; 8 //mod放在bi里,余数放在ai里 9 ll mul(ll a,ll b,ll mod){ 10 //返回a*b%mod的值,怕爆long long来着 11 ll res=0; 12 while(b>0) 13 { 14 if(b&1) res=(res+a)%mod; 15 a=(a+a)%mod; 16 b>>=1;

UVA 11754 Code Feat 中国剩余定理+枚举

对着背影说爱祢 提交于 2019-12-01 14:06:00
Code FeatUVA - 11754 题意:给出c个彼此互质的x i ,对于每个x i ,给出ki个y j ,问前s个ans满足ans%x i 的结果在y j 中有出现过。 一看便是个中国剩余定理,但是同余方程组就有k i 的乘积种组合,而k i 的乘积最大是1e18,直接中国剩余定理肯定不是的,只能对k i 的乘积稍微小的时候才能使用。 而当k i 的乘积很大时,便说明对于每个x i 它的y j 都很多,那么我们挑选其中一组x i ,设ans=temp*x i +y j, temp不需要枚举到很大便能满足其他的%x i =y j , 至于那组x i 的选择,因为我们是要枚举得更快,所有便是y j 尽可能的多,x i 尽可能的大,也就是k i /x i 最小。 最后注意输出格式上,空行的输出。 1 #include<cstdio> 2 #include<set> 3 using namespace std; 4 typedef long long ll; 5 const int N=15; 6 int n,m; 7 ll bb[N],cc[N],cp; 8 set<ll> ss[N]; 9 ll exgcd(ll a,ll b, ll &x,ll &y){ 10 if(!b){ 11 x=1; 12 y=0; 13 return a; 14 } 15 ll g=exgcd(b