标签:array string res ret 回归 syn 同余方程 div 剩余定理
题意:求解模线性同余方程组
解题关键:扩展中国剩余定理求解。两两求解。
$\begin{array}{l}
x = {r_1}\bmod {m_1}\\
x = {r_2}\bmod {m_2}
\end{array}$
为了代码的符号清晰,将转化后的系数都为正,故如下设方程。
$\begin{array}{l}
x = {r_1} - {k_1}{m_1}\\
x = {r_2} + {k_2}{m_2}
\end{array}$
${r_1} - {r_2} = {k_2}{m_2} + {k_1}{m_1}$
以上其实是另一个模线性同余方程组。
考虑$ax + by = c$
由模线性同余方程的存在定理:$\gcd (a,b)|c$
$\begin{array}{l}
\frac{a}{{\gcd (a,b)}}x + \frac{b}{{\gcd (a,b)}} = \frac{c}{{\gcd (a,b)}}\\
x \equiv {(\frac{a}{{\gcd (a,b)}})^{ - 1}}\frac{c}{{\gcd (a,b)}}\bmod (\frac{b}{{\gcd (a,b)}})
\end{array}$
回归原式:
$x$即为${k_1}$
推出原式中的$x$
$x = {r_1} - {k_1}{m_1} = {r_1} - {m_1}{(\frac{{{m_1}}}{{\gcd ({m_1},{m_2})}})^{ - 1}}\frac{{{r_2} - {r_1}}}{{\gcd ({m_1},{m_2})}}\bmod \frac{{{m_1}{m_2}}}{{\gcd ({m_1},{m_2})}}$
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 using namespace std; 8 typedef long long ll; 9 ll x,y,r[20002],m[20002],n; 10 ll extgcd(ll a,ll b,ll &x,ll &y){ 11 ll d=a; 12 if(b) d=extgcd(b,a%b,y,x),y-=a/b*x; 13 else x=1,y=0; 14 return d; 15 } 16 ll excrt(int n,ll *m,ll *r){ 17 ll M=m[0],pre=r[0],d;//a是模数 18 for(int i=1;i<n;i++){ 19 d=extgcd(M,m[i],x,y); 20 if((pre-r[i])%d!=0) return -1; 21 x=(pre-r[i])/d*x%m[i]; 22 pre-=x*M; 23 M=M/d*m[i];//lcm 24 pre%=M; 25 } 26 return (pre%M+M)%M; 27 } 28 int main(){ 29 ios::sync_with_stdio(0); 30 while(cin>>n){ 31 for(int i=0;i<n;i++) cin>>m[i]>>r[i]; 32 ll ans=excrt(n,m,r); 33 printf("%lld\n",ans); 34 } 35 }
[poj2891]Strange Way to Express Integers(扩展中国剩余定理)
标签:array string res ret 回归 syn 同余方程 div 剩余定理
原文地址:http://www.cnblogs.com/elpsycongroo/p/7617436.html