[数论] 同余方程组 poj2891 Strange Way to Express Integers

4 篇文章 0 订阅

poj2891 Strange Way to Express Integers:http://poj.org/problem?id=2891

其实应该是这样的:
P=b1(mod a1); (P%a1=b1)
P =b2(mod a2);
P =b3(mod a3);
……
P =bn(mod an);
给出a,b 求P

解:
第一条:a1*x+b1= P
第二条:a2*y+b2= P
第一条减去第二条: a1*x - a2*y = b2-b1
设A=a1,B=-a2,K=b2-b1,得到了A*x+B*y=K 标准同余方程
利用exgcd就可得解
(实际调用exgcd的时候不理会a2前面的负号)

如果K%d!=0,无解
否则,X=[ (x* K/d)%(B/d)+(B/d) ]%(B/d)

(LCU表示最小公倍数)
P= a1*X+b1+ 若干倍的LCU(a1,a2)
(或者把Y=(K-AX)/B,再P=a2*Y+b2+ 若干倍的LCU(a1,a2))
所以新的b= a1*x+b1,新的a= LCU(a1,a2),
把新的b当成b1,新的a当成a1,再去和a3和b3结合,一直到最后结束,最后的b就是X

同余方程(拓展欧几里得算法):http://blog.csdn.net/qq_36038511/article/details/76887494

代码~~

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
    if (a==0)
    {
        x=0;y=1;
        d=b;
    }
    else
    {
        LL tx,ty;
        exgcd(b%a,a,d,tx,ty);
        x=ty-(b/a)*tx;
        y=tx;
    }
}
int main()
{
    LL a,b,d,x,y,b1,b2,m1,m2,A,B,K;
    int n;
    while (scanf("%d",&n)!=EOF)
    {
        bool u=true;
        scanf("%lld%lld",&m1,&b1);
        for (int i=2;i<=n;i++)
        {
            scanf("%lld%lld",&m2,&b2);
            A=m1;B=m2;K=b2-b1;
            exgcd(A,B,d,x,y);
            if (K%d!=0) u=false;
            x=((x*(K/d)%(B/d))+(B/d))%(B/d);
            b1=x*m1+b1;
            m1=m1*m2/d;
        }
        if (u==false) printf("-1\n");
        else printf("%lld\n",b1);
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值