【GCD Table】 若选中的起始位置为(i,j)(i,j)(i,j)​,则:

<mstyle displaystyle="false" scriptlevel="0">{<mstyle displaystyle="false" scriptlevel="0">gcd(i,j))</mstyle><mstyle displaystyle="false" scriptlevel="0">=</mstyle><mstyle displaystyle="false" scriptlevel="0">a1</mstyle><mstyle displaystyle="false" scriptlevel="0">gcd(i,j+1))</mstyle><mstyle displaystyle="false" scriptlevel="0">=</mstyle><mstyle displaystyle="false" scriptlevel="0">a2</mstyle><mstyle displaystyle="false" scriptlevel="0">gcd(i,j+2))</mstyle><mstyle displaystyle="false" scriptlevel="0">=</mstyle><mstyle displaystyle="false" scriptlevel="0">a3</mstyle></mstyle><mstyle displaystyle="false" scriptlevel="0"></mstyle><mstyle displaystyle="false" scriptlevel="0">{<mstyle displaystyle="false" scriptlevel="0">j</mstyle><mstyle displaystyle="false" scriptlevel="0"></mstyle><mstyle displaystyle="false" scriptlevel="0">0(mod<mtext> </mtext><mtext> </mtext>a1)</mstyle><mstyle displaystyle="false" scriptlevel="0">j</mstyle><mstyle displaystyle="false" scriptlevel="0"></mstyle><mstyle displaystyle="false" scriptlevel="0">1(mod<mtext> </mtext><mtext> </mtext>a2)</mstyle><mstyle displaystyle="false" scriptlevel="0">j</mstyle><mstyle displaystyle="false" scriptlevel="0"></mstyle><mstyle displaystyle="false" scriptlevel="0">2(mod<mtext> </mtext><mtext> </mtext>a3)</mstyle></mstyle>\begin{matrix} \left\{\begin{matrix} gcd(i,j)) &=& a_1 \\ gcd(i,j+1)) &=& a_2 \\ gcd(i,j+2)) &=& a_3 \end{matrix}\right. & \Leftrightarrow & \left\{\begin{matrix} j &\equiv& 0(\mod a_1) \\ j &\equiv& -1 (\mod a_2) \\ j &\equiv& -2 (\mod a_3) \end{matrix}\right. \end{matrix}gcd(i,j))gcd(i,j+1))gcd(i,j+2))===a1a2a3jjj0(moda1)1(moda2)2(moda3)

上式可以通过excrt求得jjj​​​​​的通解:j=j0+Mx,<mtext> </mtext>M=lcm(a1,a2...ak)j=j_0+M\cdot x,\ M=lcm(a_1,a_2...a_k)j=j0+Mx, M=lcm(a1,a2...ak)​​​,且iii​​​​​​​​​是MMM​​​​​​​​​​​的倍数,i=M+Myi=M+M\cdot yi=M+My

g=gcd(M,j0)g=gcd(M,j_0)g=gcd(M,j0)​,g=gcd(M+My,j0+Mx)g'=gcd(M+M\cdot y,j_0+M\cdot x)g=gcd(M+My,j0+Mx)​,可以看出ggg|g'gg

只需要判断j=j0,i=Mj=j_0,i=Mj=j0,i=M​是否成立就行了,因为gcd(i,j+t)gcd(i,j+t)gcd(i,j+t)有可能是at+1a_{t+1}at+1​​​​的倍数,这样条件就不成立。

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e4 + 10;

int exgcd(int a, int b, int &x, int &y) {
    if (!b) {
        x = 1, y = 0;
        return a;
    }
    int nx, ny;
    int d = exgcd(b, a % b, nx, ny);
    x = ny;
    y = nx - a / b * ny;
    return d;
}

int lcm(int a, int b) { return a / __gcd(a, b) * b; }

pair<int, int> excrt(int k, int *a, int *r) {
    int M = r[1], ans = a[1];
    for (int i = 2; i <= k; i++) {
        int x0, y0;
        int c = a[i] - ans;
        int g = exgcd(M, r[i], x0, y0);
        if (c % g != 0) return {-1, -1};
        x0 = (__int128)x0 * (c / g) % (r[i] / g);
        ans = x0 * M + ans;
        M = lcm(M, r[i]);
        ans = (ans % M + M) % M;
    }
    return {ans, M};
}

int n, m, k, a[N];
int b[N];
signed main() {
    cin >> n >> m >> k;
    for (int i = 1; i <= k; i++) cin >> a[i], b[i] = -(i - 1);

    pair<int, int> x = excrt(k, b, a);
    if (x.first == 0) x.first = x.second;

    if (x.first > m - k + 1 || x.second > n || x.first == -1) {
        cout << "NO";
    } else {
        for (int i = 0; i < k; i++)
            if (__gcd(x.first + i, x.second) != a[i + 1]) {
                cout << "NO";
                return 0;
            }
        cout << "YES";
    }
    return 0;
}