POJ2891 Strange Way to Express Integers 不互质中国剩余定理
Posted legend_PawN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2891 Strange Way to Express Integers 不互质中国剩余定理相关的知识,希望对你有一定的参考价值。
题意是求同余方程组的最小正整数解,首先肯定想到用中国剩余定理,但题目中并没有限制模数m[i]两两互质,就不能直接用中国剩余定理,需要注意两个问题:
1.同余方程式是否有解:对任意两个同余方程:
如果gcd (m[i],m[j]) 能够整除 (b[j]−b[i]) ,该方程组有解,否则无解
2.怎样这样的同余方程式,这里采用的是合并同余方程式的方法,依次为例:
x≡2 (mod 16)x≡6 (mod 12)
相当于
x=16p+2x=12q+6⇒3x=48p+64x=48q+24
能够得到:
x=48(p−q)+18⇒x≡18 (mod 48)
从而,我们能够得到一般的合并方程式的方法:
x≡b[i] (mod m[i])x≡b[j] (mod m[j])⇒x≡b (mod m)
lcm=[m[i],m[j]]t[i]=lcmm[i] t[j]=lcmm[j]⇒m=lcm⇒b=| b[i]t[i]−b[j]t[j]|
这样就顺利完成了同余方程的合并
下面给出不互质CRT的AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll Mod;
ll gcd(ll a, ll b)
return b==0 ? a : gcd(b,a%b);
ll ex_gcd(ll a,ll b,ll&x,ll& y)
if(a==0 &&b==0)
return -1;
if(b==0)
x=1;y=0;return a;
ll d=ex_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
ll inv(ll a, ll n)
ll x,y;
ll t=ex_gcd(a,n,x,y);
if(t!=1)
return -1;
return (x%n+n)%n;
bool merge(ll b1, ll m1, ll b2, ll m2, ll& b3, ll& m3) //将两个同余方程x=b1(mod m1),x=b2(mod m2)合并成一个同余方程x=b3(mod m3)
ll d=gcd(m1,m2);
ll c=b2-b1;
if(c%d)
return false;
c=(c%m2+m2)%m2;
c/=d;m1/=d;m2/=d;
c*=inv(m1,m2);
c%=m2;
c*=m1*d;
c+=b1;
m3=m1*m2*d;
b3=(c%m3+m3)%m3;
//cout<<a3<<" "<<n3<<endl;
return true;
//求模线性方程组x=ai(mod ni),ni可以不互质
ll China_Reminder2(int len,ll b[],ll m[])
ll b1=b[0],m1=m[0];
ll b2,m2;
for(int i=1;i<len;i++)
ll bb,mm;
b2=b[i],m2=m[i];
if(!merge(b1,m1,b2,m2,bb,mm))
return -1;
b1=bb;
m1=mm;
Mod=m1;
return (b1%m1+m1)%m1;
ll b[1000],m[1000];
int main()
//freopen("input.txt","r",stdin);
int k;
while(scanf("%d",&k)!=EOF)
for(int i=0;i<k;i++)
scanf("%lld %lld",&m[i],&b[i]);
printf("%lld\\n",China_Reminder2(k,b,m));
return 0;
以上是关于POJ2891 Strange Way to Express Integers 不互质中国剩余定理的主要内容,如果未能解决你的问题,请参考以下文章
POJ 2891 Strange Way to Express Integers
poj 2891 Strange Way to Express Integers 2012-09-05
POJ2891Strange Way to Express Integers(拓展CRT)
POJ2891Strange Way to Express Integers