poj2891 Strange Way to Expres Integers

题目链接;https://www.acwing.com/problem/content/description/206/
题目描述:
给定2n个整数a1,a2,…,an和m1,m2,…,mn,求一个最小的非负整数x,满足∀i∈[1,n],x≡mi(mod ai)


输入格式

第1行包含整数n。

第2…n行:每i+1行包含两个整数ai
和mi

,数之间用空格隔开。
输出格式

输出最小非负整数x,如果x不存在,则输出-1。
如果存在x,则数据保证x一定在64位整数范围内。
数据范围

1≤ai≤231−1
,
0≤mi<ai
1≤n≤25

输入样例:

2
8 7
11 9

输出样例:

31

分析:
这看似中国剩余定理,实则却不满足中国剩余定理。
我们可以先考虑第一个和第二个式子,我们把满足这两个式子的解先求出来。通过归纳,即可得正确答案。
看到一篇初中生的巨巨博客,讲的很好。故我在此不做过多表述了。
参考博客:https://www.acwing.com/solution/acwing/content/3539/#comment_3155

#include"stdio.h"
#include"string.h"
#include"math.h"
#include"algorithm"
using namespace std;
typedef long long ll;

ll n,a1,m1;

ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b == 0)
    {
        x = 1; y = 0; return a;
    }
    ll d = exgcd(b,a%b,x,y);
    ll z = x; x = y; y = z - y * (a / b);
    return d;
}
int main()
{
    scanf("%lld",&n);  n -= 1;
    scanf("%lld%lld",&a1,&m1);
    ll k1,k2;
    while(n --)
    {
        ll a2,m2;
        scanf("%lld%lld",&a2,&m2);
        ll c = m2 - m1;
        ll d = exgcd(a1,-a2,k1,k2);
        if(c % d)
        {
            printf("-1\n"); return 0;
        }
        k1 *= c / d;
        k1 = (k1 % abs(a2 / d) + abs(a2 / d)) % abs(a2 / d);
        m1 = k1 * a1 + m1; a1 = abs(a1 * a2 / d);
    }
    printf("%lld\n",m1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值