Untitled

mail@pastecode.io avatar
unknown
c_cpp
a year ago
4.6 kB
1
Indexable
Never
#include "bits/stdc++.h"
using namespace std;

#ifdef LOCAL
#include "debug.h"
#else
#define debug(x...)
#endif

#define int long long

constexpr int MOD1 = 1e9 + 7;
constexpr int MOD2 = 1e9 + 9;
constexpr int k1 = 223;
constexpr int k2 = 309;

inline int md1(long long n) {
    n %= MOD1;
    if (n < 0) {
        n += MOD1;
    }
    return n;
}

inline int md2(long long n) {
    n %= MOD2;
    if (n < 0) {
        n += MOD2;
    }
    return n;
}

void solve() {
    vector<int> p1(100000), p2(100000);
    p1[0] = 1;
    p2[0] = 1;
    for (int i = 1; i < 100000; i++) {
        p1[i] = md1(p1[i - 1] * k1);
        p2[i] = md2(p2[i - 1] * k2);
    }
    int n, m;
    cin >> n >> m;
    vector<int> A(n), B(m);
    for (int &i : A) {
        cin >> i;
    }
    for (int &i : B) {
        cin >> i;
    }
    vector<int> rA = A, rB = B;
    reverse(rA.begin(), rA.end());
    reverse(rB.begin(), rB.end());
    vector<pair<int, int>> hashA(n + 1), hashrA(n + 1), hashB(m + 1), hashrB(m + 1);
    for (int i = n - 1; i >= 0; i--) {
        hashA[i] = {md1(hashA[i + 1].first * k1 + A[i]), md2(hashA[i + 1].second * k2 + A[i])};
        hashrA[i] = {md1(hashrA[i + 1].first * k1 + rA[i]), md2(hashrA[i + 1].second * k2 + rA[i])};
    }
    for (int i = m - 1; i >= 0; i--) {
        hashB[i] = {md1(hashB[i + 1].first * k1 + B[i]), md2(hashB[i + 1].second * k2 + B[i])};
        hashrB[i] = {md1(hashrB[i + 1].first * k1 + rB[i]), md2(hashrB[i + 1].second * k2 + rB[i])};
    }
    auto getA = [&](int l, int r) -> pair<int, int> {
        return {md1(hashA[l].first - md1(hashA[r + 1].first * p1[r - l + 1])), md2(hashA[l].second - md2(hashA[r + 1].second * p2[r - l + 1]))};
    };

    auto getB = [&](int l, int r) -> pair<int, int> {
        return {md1(hashB[l].first - md1(hashB[r + 1].first * p1[r - l + 1])), md2(hashB[l].second - md2(hashB[r + 1].second * p2[r - l + 1]))};
    };

    auto getrA = [&](int l, int r) -> pair<int, int> {
        return {md1(hashrA[l].first - md1(hashrA[r + 1].first * p1[r - l + 1])), md2(hashrA[l].second - md2(hashrA[r + 1].second * p2[r - l + 1]))};
    };

    auto getrB = [&](int l, int r) -> pair<int, int> {
        return {md1(hashrB[l].first - md1(hashrB[r + 1].first * p1[r - l + 1])), md2(hashrB[l].second - md2(hashrB[r + 1].second * p2[r - l + 1]))};
    };

    auto can = [&](int len) -> bool {
        int half = len / 2;
        if (len % 2 == 1) {
            vector<pair<int, int>> S;
            for (int i = half; i < n - half; i++) {
                pair<int, int> get = getA(i - half, i), getr = getrA(n - i - half - 1, n - i - 1);
                S.emplace_back(md1(get.first - getr.first), md2(get.second - getr.second));
            }
            sort(S.begin(), S.end());
            for (int i = half; i < m - half; i++) {
                pair<int, int> get = getB(i - half, i), getr = getrB(m - i - half - 1, m - i - 1);
                if (binary_search(S.begin(), S.end(), make_pair(md1(getr.first - get.first), md2(getr.second - get.second)))) {
                    return true;
                }
            }
        } else {
            vector<pair<int, int>> S;
            for (int i = half - 1; i < n - half; i++) {
                pair<int, int> get = getA(i - half + 1, i), getr = getrA(n - i - half - 1, n - i - 2);
                S.emplace_back(md1(get.first - getr.first), md2(get.second - getr.second));
            }
            sort(S.begin(), S.end());
            for (int i = half - 1; i < m - half; i++) {
                pair<int, int> get = getB(i - half + 1, i), getr = getrB(m - i - half - 1, m - i - 2);
                if (binary_search(S.begin(), S.end(), make_pair(md1(getr.first - get.first), md2(getr.second - get.second)))) {
                    return true;
                }
            }
        }
        return false;
    };
    // odd
    int L = 0, R = (min(n, m)) / 2;
    while (L + 1 != R) {
        int M = (L + R) / 2;
        if (can(M * 2 + 1)) {
            L = M;
        } else {
            R = M;
        }
    }
    // even
    int L1 = 0, R1 = (min(n, m) + 1) / 2;
    while (L1 + 1 != R1) {
        int M = (L1 + R1) / 2;
        if (can(M * 2)) {
            L1 = M;
        } else {
            R1 = M;
        }
    }
    cout << max(L * 2 + 1, L1 * 2);
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int tests = 1;
    // cin >> tests;
    while (tests--) {
        solve();
    }
    return 0;
}