迭代法求线性联立同余式(POJ_2891, ZOJ_3562)
中国剩余定理应该可以,但是x=ai%mi(1<=i<=k),这里的mi没有限制互质,所以不能直接套用中国剩余定理.
修改的话外加判断条件,思路不太清晰,后来看Rosen的"数论及其应用",发现联立的同余方程的迭代解法.
迭代解法中不需要考虑mi是否互质的情况,最终化简结果就是我们要求的解,中间可能无解时,直接跳出.
基本思路类似消元,参照<初等数论及其应用>.
附代码:
--------------------------------------------------------------------------------------------------------
bool calc(LL a,LL b,LL m,LL& p,LL &q)
{
LL d=gcd(a,m);
if(b%d)
return false;
LL x,y;
gcd(a,m,d,x,y);
x*=b/d;
p=x,q=m/d;
p=mod(p,q);
return true;
}
LL work()
{
LL a,b,m;
LL p=ri[0],q=ai[0];
bool bingo=true;
for(int i=1;i<k;i++)
{
a=q,m=ai[i];
b=mod(ri[i]-p,m);
LL tmp = gcd(a, m);
if(b % tmp)
{
bingo = false;
break;
}
a /= tmp, b /= tmp, m /= tmp;
//printf("%I64d %I64d %I64d \n",a,b,m);
LL in = inv(a, m);
if(-1 == in)
{
bingo = false;
break;
}
b = mod(b * in, m);
p = q * b + p;
q = q * m;
p = mod(p, q);
}
if(!bingo)
{
return -1;
}
return p;
}
-------------------------------------------------------------------------------------------------------
当然还有一个更通用的模板(系数不为1),来自wata:
ZOJ Monthly, December 2011 B题(ZOJ_3562)C++切掉:)
另外,Edward_mj牛的一篇文章,讲了下算法过程:传送门