题目描述
给定一个序列,多次询问一段区间 [l,r],求区间中相同的数的最远间隔距离。
序列中两个元素的间隔距离指的是两个元素下标差的绝对值。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<deque>
#include<map>
#include<vector>
#include<cmath>
#define ll long long
#define llu unsigned ll
using namespace std;
const double eps = 1e-8;
const ll lnf = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int mod = 1e9 + 7;
int a[maxn], b[maxn], ans[maxn], pos[maxn], res = 0;
int mi[maxn], ma[maxn], st[maxn];
struct node
{
int l, r, id;
}q[maxn];
bool cmp(const node& a, const node& b)
{
if (pos[a.l] != pos[b.l]) return pos[a.l] < pos[b.l];
else return a.r < b.r;
}
int get(int l, int r)
{
int ans = 0, cnt = 0;
for (int i = l;i <= r;i++)
{
if (!mi[a[i]]) mi[a[i]] = i, st[++cnt] = a[i];
else ans = max(ans, i - mi[a[i]]);
}
while (cnt)
mi[st[cnt--]] = 0;
return ans;
}
int main(void)
{
int n, m;
scanf("%d", &n);
for (int i = 1;i <= n;i++)
scanf("%d", &a[i]), b[i] = a[i];
sort(b + 1, b + n + 1);
int pc = unique(b + 1, b + n + 1) - (b + 1);
for (int i = 1;i <= n;i++)
a[i] = lower_bound(b + 1, b + pc + 1, a[i]) - b;
scanf("%d", &m);
int t = sqrt(m);
for (int i = 1;i <= n;i++)
pos[i] = (i - 1) / t + 1;
for (int i = 1;i <= m;i++)
scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;
sort(q + 1, q + m + 1, cmp);
int len = pos[n];
for (int i = 1, j = 1;j <= len;j++)
{
int askr = min(j * t, n) + 1, ql = askr, qr = ql - 1;
int res = 0, cnt = 0;
for (;pos[q[i].l] == j;i++)
{
if (pos[q[i].r] == j)
{
ans[q[i].id] = get(q[i].l, q[i].r);
continue;
}
while (qr < q[i].r)
{
++qr;
ma[a[qr]] = qr;
if (!mi[a[qr]]) mi[a[qr]] = qr, st[++cnt] = a[qr];
res = max(res, qr - mi[a[qr]]);
}
int now = res;
while (ql > q[i].l)
{
--ql;
if (!ma[a[ql]]) ma[a[ql]] = ql;
res = max(res, ma[a[ql]] - ql);
}
ans[q[i].id] = res;
while (ql <= askr)
{
if (ma[a[ql]] == ql) ma[a[ql]] = 0;
ql++;
}
res = now;
}
while (cnt)
ma[st[cnt]] = mi[st[cnt]] = 0, cnt--;
}
for (int i = 1;i <= m;i++)
printf("%d\n", ans[i]);
return 0;
}