玄关求调!
查看原帖
玄关求调!
534872
tony0530楼主2025/1/29 20:05
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>

#define int long long

using namespace std;

const int N = 100010;

int n, m, len;
int w[N], cnt[N];
int ans[N];
map<int, int> hash1;
struct Query
{
    int id, l, r;
}q[N];
vector<int> nums;

int get(int x)
{
    return x / len;
}

bool cmp(const Query& a, const Query& b)
{
    int i = get(a.l), j = get(b.l);
    if (i != j) return i < j;
    return a.r < b.r;
}

void add(int l, int x, int& res)
{
    cnt[x] ++ ;
    if(hash1.count(x) == false) hash1[x] = l;
    else res = max(res, abs(l - hash1[x]));
}

signed main()
{
    scanf("%lld", &n);
    len = sqrt(n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]), nums.push_back(w[i]);
    scanf("%lld", &m);
    sort(nums.begin(), nums.end());
    nums.erase(unique(nums.begin(), nums.end()), nums.end());
    for (int i = 1; i <= n; i ++ )
        w[i] = lower_bound(nums.begin(), nums.end(), w[i]) - nums.begin();

    for (int i = 0; i < m; i ++ )
    {
        int l, r;
        scanf("%lld%lld", &l, &r);
        q[i] = {i, l, r};
    }
    sort(q, q + m, cmp);

    for (int x = 0; x < m;)
    {
        int y = x;
        while (y < m && get(q[y].l) == get(q[x].l)) y ++ ;
        int right = get(q[x].l) * len + len - 1;

        // 暴力求块内的询问
        while (x < y && q[x].r <= right)
        {
            int res = 0;
            hash1.clear();
            int id = q[x].id, l = q[x].l, r = q[x].r;
            for (int k = l; k <= r; k ++ ) add(k, w[k], res);
            ans[id] = res;
            for (int k = l; k <= r; k ++ ) cnt[w[k]] -- ;
            x ++ ;
        }

        // 求块外的询问
        int res = 0;
        hash1.clear();
        int i = right, j = right + 1;
        while (x < y)
        {
            int id = q[x].id, l = q[x].l, r = q[x].r;
            while (i < r) add( ++ i, w[i], res);
            int backup = res;
            map<int, int> hash2 = hash1;
            while (j > l) add(j, w[ -- j], res);
            ans[id] = res;
            while (j < right + 1) cnt[w[j ++ ]] -- ;
            res = backup;
            hash1 = hash2;
            x ++ ;
        }
        memset(cnt, 0, sizeof cnt);
        hash1.clear();
    }

    for (int i = 0; i < m; i ++ ) printf("%lld\n", ans[i]);
    return 0;
}

2025/1/29 20:05
加载中...