1. 程式人生 > >擴充套件中國剩餘定理詳解

擴充套件中國剩餘定理詳解

前言

閱讀本文前,推薦先學一下中國剩餘定理。其實不學也無所謂,畢竟兩者沒啥關係

擴充套件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}$

我們用$(a,b)$表示$a,b$的最大公約數

在這裡需要注意,這個方程有解的條件是

$\left( m_{1},m_{2}\right) |\left( c_{2}-c_{1}\right)$,因為後面會用到$\dfrac {\left( c_{2}-c_{1}\right) }{\left( m_{2},m_{1}\right) }$這一項,如果不整除的話肯定會出現小數。

對於上面的方程,兩邊同除$(m_1,m_2)$

$$\dfrac {m_{1}k_{1}}{\left( m_{1},m_{2}\right) }=\dfrac {c_{2}-c_{1}}{\left( m_{1},m_{2}\right) }+\dfrac {m_{2}k_{2}}{\left( m_{1},m_{2}\right) }$$

$$\dfrac {m_{1}}{\left( m_{1},m_{2}\right) }k_{1}=\dfrac {c_{2}-c_{1}}{\left( m_{1},m_{2}\right) }+\dfrac {m_{2}}{\left( m_{1},m_{2}\right) }k_{2}$$

轉換一下

$$\dfrac {m_{1}}{\left( m_{1},m_{2}\right) }k_{1} \equiv \dfrac {c_{2}-c_{1}}{\left( m_{1},m_{2}\right) } (mod\ \dfrac {m_{2}}{\left( m_{1},m_{2}\right) })$$

此時我們已經成功把$k_2$消去了。

同餘式兩邊同除$\dfrac {m_{1}}{\left( m_{1},m_{2}\right) }$

$$k_1\equiv inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}\pmod {{m_2\over(m_1,m_2)}}$$

$inv(a,b)$表示$a$在模$b$意義下的逆元

$$k_1=inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}+{{m_2\over (m_1,m_2)}}*y$$

接下來怎麼辦呢?這個式子已經化到最簡了。。

不要忘了,我們剛開始還有兩個式子。我們把$k_1$待回去!

$$x=inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}*m_1+y{{m_1m_2\over (m_1,m_2)}}+c_1$$

$$x\equiv inv({m_1\over(m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)}*m_1+c_1\pmod {{m_1m_2\over (m_1,m_2)}}$$

此時,整個式子中的元素我們都已經知道了

具體一點,這個式子可以看做是$$x\equiv c\pmod m$$

其中$$c=(inv({m_1\over (m_1,m_2)},{m_2\over (m_1,m_2)})*{(c_2-c_1)\over (m_1,m_2)})\%{m_2\over (m_1,m_2)}*m_1+c_1$$

$$m={m_1m_2\over (m_1,m_2)}$$

推廣一下

我們每次把兩個同餘式合併,求解之後得到一個新的同餘式。再把新的同餘式和其他的聯立,最終就可以求出滿足條件的解

程式碼

update in 2018.10.11:這份程式碼可能在較強的資料下出現乘爆long long的情況(我記得NOI2018Day2T1就是因為這個過不了大樣例)

直接把#define LL long long 改成#define LL __int128就好了

題目連結

#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
const LL MAXN = 1e6 + 10;
LL K, C[MAXN], M[MAXN], x, y;
LL gcd(LL a, LL b) {
    return b == 0 ? a : gcd(b, a % b);
}
LL exgcd(LL a, LL b, LL &x, LL &y) {
    if (b == 0) {x = 1, y = 0; return a;}
    LL r = exgcd(b, a % b, x, y), tmp;
    tmp = x; x = y; y = tmp - (a / b) * y;
    return r;
}
LL inv(LL a, LL b) {
    LL r = exgcd(a, b, x, y);
    while (x < 0) x += b;
    return x;
}
int main() {
#ifdef WIN32
    freopen("a.in", "r", stdin);
#else
#endif
    while (~scanf("%lld", &K)) {
        for (LL i = 1; i <= K; i++) scanf("%lld%lld", &M[i], &C[i]);
        bool flag = 1;
        for (LL i = 2; i <= K; i++) {
            LL M1 = M[i - 1], M2 = M[i], C2 = C[i], C1 = C[i - 1], T = gcd(M1, M2);
            if ((C2 - C1) % T != 0) {flag = 0; break;}
            M[i] = (M1 * M2) / T;
            C[i] = ( inv( M1 / T , M2 / T ) * (C2 - C1) / T ) % (M2 / T) * M1 + C1;
            C[i] = (C[i] % M[i] + M[i]) % M[i];
        }
        printf("%lld\n", flag ? C[K] : -1);
    }
    return 0;
}

再放道裸題

http://acm.hdu.edu.cn/showproblem.php?pid=1573

題解

相關推薦

擴充套件中國剩餘定理

前言 閱讀本文前,推薦先學一下中國剩餘定理。其實不學也無所謂,畢竟兩者沒啥關係 擴充套件CRT 我們知道,中國剩餘定理是用來解同餘方程組 $$\begin{cases}x\equiv c_{1}\left( mod\ m_{1}\right) \\ x\equiv c_{2}\left( mod\ m

中國剩餘定理

引入 我國古代數學著作《孫子算經》中有一道題目,它的描述是這樣的 今有物不知其數,三三數之餘二;五五數之餘三;七七數之餘二。問物幾何? 這道題用現代數學理論來看,無非就是解一個方程 \begin{cases}x\equiv 2\left( mod\ 3\right) \\x\equiv 3\l

學習筆記 - 中國剩餘定理&擴充套件中國剩餘定理

中國剩餘定理&擴充套件中國剩餘定理 NOIP考完回機房填坑    ◌ 中國剩餘定理 處理一類相較擴充套件中國剩餘定理更特殊的問題:   在這裡要求 對於任意i,j(i≠j),gcd(mi,mj)=1 (就是互素) 不互素的話就只能用擴充套件

bzoj 1573 X問題【擴充套件中國剩餘定理

擴充套件中國剩餘定理的板子,合併完之後算一下範圍內能取幾個值即可(記得去掉0) #include<iostream> #include<cstdio> #include<cmath> using namespace std; const int N=15; int T,n

[模板]中國剩餘定理/擴充套件中國剩餘定理

中國剩餘定理(crt) 求解同餘方程組$\{x=a_i (\mod b_i)$,要求$b_i$互質 有公式$x = \sum{a_iM_it_i} , lcm是b的最小公倍數, M_i=lcm/b_i , t_i=M_i^{-1}(\mod b_i)$ 因為感覺被excrt完爆所以看看得了233 擴充

Strange Way to Express Integers [擴充套件中國剩餘定理]

Description Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is described as f

擴充套件中國剩餘定理模板

{x≡a1(modm1)x≡a2(modm2)\begin{cases}x \equiv a_1 \pmod{m_1} \\x \equiv a_2 \pmod{m_2} \end{cases}{x≡a

部落格處女作:中國剩餘定理擴充套件中國剩餘定理

各位好啊,這裡是蒟蒻gigo_64的第一篇部落格,,這裡我們開始啦。 本文需要讀者知曉擴充套件歐幾里得,如果不會請點選這個大佬的連結;https://blog.csdn.net/sslz_fsy/article/details/81566257 中國剩餘定理是用來求解一個方程組的。這個方

poj3708 擴充套件中國剩餘定理+大數轉d進位制

#include<cstdio> #include<cstring> using namespace std; #define ll long long #define pf printf #define sf scanf const int maxn=1000+5; int d

[洛谷P4777]【模板】擴充套件中國剩餘定理(EXCRT)

題目大意:給你一些關於$x$的方程組:$$\begin{cases}x\equiv a_1\pmod{mod_1}\\x\equiv a_2\pmod{mod_2}\\\vdots\\x\equiv a_n\pmod{mod_n}\end{cases}$$求解$x$的最小非負整數解($\gcd(mod_1,m

中國剩餘定理(孫子定理)

問題:今有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。問物幾何? 說明白一點就是說,存在一個數x,除以3餘2,除以5餘三,除以7餘二,然後求這個數。上面給出瞭解法。再明白這個解法的原理之前,需要先知道一下兩個定理。 定理1:幾個數相加,如果存在一個加數,不能被數a整除,那麼它們的和,就不能被整數a

中國剩余定理(孫子定理) (轉)

col == 了解 turn 情況下 歐幾裏得算法 得到 輾轉相除法 人的 原文:https://www.cnblogs.com/freinds/p/6388992.html 問題:今有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。問物幾何? 說明白一點就是

擴充套件歐幾里得及中國剩餘定理

Exgcd 擴充套件歐幾里得 void exgcd(int a,int b,int &x,int &y){ if(!b){x=1,y=0;return;} exgcd(b,a%b,x,y);b-=y*(a/b); } 對於 \(gcd(a,b)=g\) ,\(a\time

中國剩餘定理擴充套件 Lucas定理擴充套件 學習筆記

中國剩餘定理 問題 求同餘方程組 ⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪x≡c1(modm1)x≡c2(modm2)x≡c3(modm3)...x≡ck(modmk){x≡c1(modm1)x≡c2(modm2)x≡c3(modm3)...x≡ck(modmk

[BZOJ2142]-擴充套件Lucas+中國剩餘定理

說在前面 今天機房裡考了一套自稱是NOIP模擬的題。然後還全能在BZOJ上找得到…還是省選題!!?反正考場上只能全寫暴力…心塞塞。不過裡面有道狀壓感覺應該能寫(至少知識點沒有超綱)BZOJ4565,先放在這裡,哪天看見了就去寫一寫。(還有一道是BZOJ2125

擴充套件GCD 中國剩餘定理(CRT) 乘法逆元模版

extend_gcd: 已知 a,b (a>=0,b>=0) 求一組解 (x,y) 使得 (x,y)滿足 gcd(a,b) = ax+by 下面程式碼中d = gcd(a,b),順便求出gcd 可以擴充套件成求等式 ax+by = c,但c必須是d的倍數才有解,

【Codeforces2015ICL,Finals,Div. 1#J】Ceizenpok's formula(擴充套件Lucas定理+中國剩餘定理

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> usin

[BZOJ2142]禮物-擴充套件lucas定理-中國剩餘定理

禮物 Description 一年一度的聖誕節快要來到了。每年的聖誕節小E都會收到許多禮物,當然他也會送出許多禮物。不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的禮物會越多。小E從商店中購買了n件禮物,打算送給m個人,其中送給第i個人

poj 2891 Strange Way to Express Integers 中國剩餘定理模板

Description   Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is descr

Poj 1006 Biorhythms 中國剩餘定理

Description Some people believe that there are three cycles in a person's life that start the day he or she is born. These three cycles are the phys