HDU 1573 - X问题 (中国剩余定理不互质情况)

思路

这题是中国剩余定理模r[i]的时候r[i]不互质的情况。

这时候就要用扩展欧几里得一个一个合并了。

就是说先算a[0]和a[1]的答案,再用上一个和a[2]算。以此类推。

简单些一下过程备忘。

$C \bmod a_1 = r_1$, $C \bmod a_2 = r_2$
$xa_1 + r_1 = y * a_2 + r_2$
$x
a_1 + y^{‘} * a_2 = r2 - r1$
利用扩展欧几里得求出一个解x

可得$C = x*a_1 + r_1$

然后这个C就成为新的r1。这里搞不懂。$a_1$变成$LCM(a_1, a_2)$

就这样

代码

void Extend_GCD(LL a, LL b, LL &d, LL &x, LL &y)
{
    if (!b) d = a, x = 1, y = 0;
    else { Extend_GCD(b, a%b, d, y, x); y -= x * (a/b); }
}
 
LL a[MAXN], r[MAXN];
 
int main()
{
    //ROP;
    int T;
    LL g;
    cin >> T;
    while (T--)
    {
        bool flag = false;
        LL n, k, tmp;
        cin >> n >> k;
        for (int i = 0; i < k; i++) cin >> a[i];
        for (int i = 0; i < k; i++) cin >> r[i];
        LL a1 = a[0], r1 = r[0];
        for (int i = 1; i < k; i++)
        {
            LL a2 = a[i], r2 = r[i], C = r2 - r1;
            LL x, y;
            Extend_GCD(a1, a2, g, x, y);
            if (C % g)
            {
                flag = true;
                break;
            }
            x = C / g * x;
            tmp = a2 / g;
            x = (x%tmp + tmp) % tmp;
            r1 = a1 * x + r1;
            a1 = a1 / g * a2;
        }
        if (flag || r1 > n) puts("0");
        else
        {
            if (!r1) cout << (n-r1) / a1 << endl;
            cout << (n-r1) / a1 + 1 << endl;
        }
    }
    return 0;
}

Powered by Jekyll and Theme by solid