204. 表达整数的奇怪方式

388 篇文章 10 订阅

Powered by:NEFU AB-IN

Link

204. 表达整数的奇怪方式

  • 题意

    给定 2n 个整数 a1,a2,…,an 和 m1,m2,…,mn,求一个最小的非负整数 x,满足 ∀i∈[1,n],x≡ai(mod mi)。

  • 思路

    注意
    以下为了方便,m和a反过来了


    前置知识: 二元一次不定方程通解
    img

    可以发现这个题的m不都互质,所以不能直接采用中国剩余定理,那么就可以推导中国剩余定理拓展版,解决 m i m_i mi不互质的问题

    核心思想将两个不定方程合并为一个不定方程,合并 n − 1 n-1 n1次就可以将 n n n个方程合并为一个方程

    CRT
    其中:

    • [ m 1 , m 2 ] [m_1, m_2] [m1,m2] 代表 m 1 , m 2 m_1, m_2 m1,m2最小公倍数 lcm
    • ( m 1 , m 2 ) (m_1, m_2) (m1,m2) 代表 m 1 , m 2 m_1, m_2 m1,m2最大公约数 gcd

    C++和python取模问题

    • C++负数取模,还是负数,所以求a模m的正余数时,(a % m + m) % m
    • python负数取模,为正数,所以求a模m的正余数时,a % m
    • 同时也是km + a最小正整数解
  • 代码

    '''
    Author: NEFU AB-IN
    Date: 2022-03-11 20:29:00
    FilePath: \ACM\Acwing\204.py
    LastEditTime: 2022-03-11 20:56:04
    '''
    
    
    def exgcd(a, b):
        global k1, k2
        if b == 0:
            k1, k2 = 1, 0
            return a
        d = exgcd(b, a % b)
        k1, k2 = k2, k1
        k2 -= (a // b) * k1
        return d
    
    
    n = int(input())
    
    m1, a1 = map(int, input().split())
    flag = 0
    for i in range(n - 1):
        m2, a2 = map(int, input().split())
        k1, k2 = 0, 0
        d = exgcd(m1, m2)
        if (a2 - a1) % d:
            flag = 1
            break
        k1 *= (a2 - a1) // d
        # k1' = k1 + k * (m2 // d) , k取任意整数
        t = m2 // d
        k1 = k1 % t  # 取最小的k1
        # x = a + km
        a1 = k1 * m1 + a1
        m1 = m1 // d * m2
    
    if flag:
        print(-1)
    else:
        print(a1 % m1)  #x的最小正整数解
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NEFU AB-IN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值