题意

给你一个 的表 , 列的元素为,然后给你一个序列,让你在表格里面找一个行的连续元素,满足

思路

这边的序列变成

因为,可以推导出

等于

很显然第一个的通解为

第二的通解,我们设为

那么可能的解为,

这样枚举判断所有解是否合法的话肯定是不行的,

我们假设是解,

那么可以得到 ,

根据方程可以知道

又因为 (因为肯定是的因子)

那么可以知道 ,因为也等于 ,所以

其它也可以用相同的方法证明

所以可以知道其他解成立的情况下,第一个解也一定成立,所以我们只需要判断第一个解就好

代码

#include <bits/stdc++.h>
using namespace std;
#define dd(x) cout << #x << " = " << x << ' '
#define de(x) cout << #x << " = " << x << '\n'
typedef long long ll;
typedef pair<ll, ll> pll;


ll exgcd(ll a, ll b, ll& x, ll& y) {
    if (!b) return x = 1, y = 0, a;
    ll g = exgcd(b, a % b, x, y);
    tie(x, y) = make_tuple(y, x - a / b * y);
    return g;
}

ll qmul(ll a, ll b, ll c) {
    ll ret = 0;
    while(b) {
        if (b & 1) {
            ret = (ret + a) % c;
        }
        a = (a + a) % c;
        b >>= 1;
    }
    return ret;
}

pll get_ans(ll p1, ll r1, ll p2, ll r2) {
    if (r1 < r2) {
        swap(r1, r2);
        swap(p1, p2);
    }
    ll x = -1, y = -1;
    ll g = exgcd(p2, p1, y, x);
    assert(g);
    ll p = p1 / g * p2;
    assert(p);
    if ((r1 - r2) % g) return pair(0ll, 0ll);
    ll d = (r1 - r2) / g;
    // ll x0 = (qmul(qmul(p2, y, p), d, p) + r2) % p;
    ll x0 = ((__int128) p2 * y % p * d % p + r2) % p;
    if (x0 < 0) {
        x0 = x0 + (-x0 + p - 1) / p * p;
    } else {
        x0 = x0 - x0 / p * p; 
    }
    if (!x0) x0 = p;
    return pair(p, x0);
}

int main() {
    ios_base::sync_with_stdio(0);cin.tie(0);
    ll n, m; cin >> n >> m;
    int k; cin >> k;
    vector<ll> a(k);
    for (int i = 0; i < k; ++i) cin >> a[i];
    if (k == 1) {
        if (n >= a[0] && m >= a[0]) cout << "YES" << '\n';
        else cout << "NO" << '\n';
        return 0;
    }
    ll L = a[0];
    for (int i = 1; i < k; ++i) {
        ll x = -1, y = -1;
        ll g = exgcd(L , a[i], x, y);
        ll l = L / g;
        assert(g);
        ll r = a[i];
        // if (l > n || r > n) return cout << "NO" << '\n', 0;
        assert(l);
        if (n / l < r) return cout << "NO" << '\n', 0;
        L = l * r;
    }
    ll p = a[0], r = 0;
    for (int i = 1; i < k; ++i) {
        auto [pp, rr] = get_ans(p, r, a[i], ((-i) % a[i] + a[i]) % a[i]);
        p = pp, r = rr;
        if (!p) return cout << "NO" << '\n', 0;
    }
    auto check = [&] (ll L, ll j0) {
        if (j0 > m - k + 1) return false;
        for (int i = 0; i < k; ++i) {
            ll x = -1, y = -1;
            ll g = exgcd(L, j0 + i, x, y);
            // dd(L), dd(j0 + i), dd(g), de(a[i]);
            if (g != a[i]) return false;
        }
        return true;
    };
    // dd(L), de(r);
    cout << (check(L, r) ? "YES" : "NO") << '\n';
    return 0;
}