MnZn刚学分块TLE求助
查看原帖
MnZn刚学分块TLE求助
610557
shinzanmonoszm 妹妹楼主2022/11/6 11:09
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
const int sz = 5e5 + 10;
const int sqsz = 1e3 + 10;
int belong[sz], f[sqsz][sqsz], ln[sz], rn[sz], arr[sz], cnt[sz], carr[sz];
std::vector<int> exi[sz];
int query(int l, int r) {
    int res = 0;
    if (belong[l] == belong[r]) {
        for (int i = l; i <= r; i++)
            res = std::max(res, ++cnt[arr[i]]);
        for (int i = l; i <= r; i++) --cnt[arr[i]];
        return res;
    }
    auto count = [](int val, int l, int r) -> int {
        return std::upper_bound(exi[val].begin(), exi[val].end(), r) -
               std::lower_bound(exi[val].begin(), exi[val].end(), l);
    };
    for (int i = l; i <= rn[belong[l]]; i++)
        res = std::max(res, count(arr[i], l, r));
    for (int i = ln[belong[r]]; i <= r; i++)
        res = std::max(res, count(arr[i], l, r));
    if (belong[l] + 1 < belong[r])
        res = std::max(res, f[belong[l] + 1][belong[r] - 1]);
    return res;
}
int main() {
    std::ios::sync_with_stdio(false);
    int n, q;
    std::cin >> n >> q;
    int lim = n / std::sqrt(q);
    for (int i = 1; i <= n; i++) std::cin >> arr[i];
    std::copy(arr + 1, arr + n + 1, carr + 1);
    std::sort(carr + 1, carr + n + 1);
    int len = std::unique(carr + 1, carr + n + 1) - carr;
    for (int i = 1; i <= n; i++)
        arr[i] = std::lower_bound(carr + 1, carr + len, arr[i]) - carr;
    for (int i = 1; i <= n; i++)
        exi[arr[i]].push_back(i);
    int tot = n / lim;
    for (int i = 1; i <= tot; i++)
        ln[i] = (i - 1) * lim + 1, rn[i] = i * lim;
    if (tot * lim < n)
        ++tot, ln[tot] = (tot - 1) * lim + 1, rn[tot] = n;
    for (int i = 1; i <= tot; i++)
        for (int j = ln[i]; j <= rn[i]; j++)
            belong[j] = i;
    for (int i = 1; i <= tot; i++) {
        int res = 0;
        for (int j = i; j <= tot; j++) {
            for (int k = ln[j]; k <= rn[j]; k++)
                res = std::max(res, ++cnt[arr[k]]);
            f[i][j] = res;
        }
        for (int j = ln[i]; j <= rn[tot]; j++) --cnt[arr[j]];
    }
    int lst = 0;
    while (q--) {
        int l, r;
        std::cin >> l >> r;
        l ^= lst, r ^= lst;
        if (l > r) std::swap(l, r);
        lst = query(l, r);
        std::cout << lst << std::endl;
    }
    return 0;
}
2022/11/6 11:09
加载中...