思路参考 https://www.luogu.com.cn/blog/_post/312290,其实就是找不同游戏,调了一下午了
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10, M = 730;
int n, q;
int a[N], b[N];
int st[M], ed[M], pos[N], f[M][M], cnt[N];
int block, num;
vector<int> in[N];
int at[N];
void build()
{
sort(b + 1, b + n + 1);
int len = unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; i ++ )
{
a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
in[a[i]].emplace_back(i);
at[i] = in[a[i]].size() - 1;
}
block = sqrt(n), num = (n - 1) / block + 1;
for (int i = 1; i <= num; i ++ )
st[i] = (i - 1) * block + 1, ed[i] = i * block;
ed[num] = n;
for (int i = 1; i <= n; i ++ ) pos[i] = (i - 1) / block + 1;
for (int i = 1; i <= num; i ++ )
{
int t = 0;
for (int j = i; j <= num; j ++ )
{
for (int k = st[j]; k <= ed[j]; k ++ )
t = max(t, ++ cnt[a[k]]);
f[i][j] = t;
}
for (int j = i; j <= num; j ++ )
for (int k = st[j]; k <= ed[j]; k ++ )
cnt[a[k]] = 0;
}
}
int query(int l, int r)
{
int x = pos[l], y = pos[r];
if (x == y)
{
int t = 0;
for (int i = l; i <= r; i ++ ) cnt[a[i]] ++, t = max(t, cnt[a[i]]);
for (int i = l; i <= r; i ++ ) cnt[a[i]] = 0;
return t;
}
int t = f[x + 1][y - 1];
for (int i = l; i <= ed[x]; i ++ )
for (int p = at[i]; p + t < in[a[i]].size() && in[a[i]][p + t] <= r; t ++ )
for (int i = st[y]; i <= r; i ++ )
for (int p = at[i]; p - t >= 0 && in[a[i]][p - t] >= l; t ++ )
return t;
}
int main()
{
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; i ++ )
scanf("%d", &b[i]), a[i] = b[i];
build();
int last = 0;
while (q -- )
{
int l, r;
scanf("%d%d", &l, &r);
l ^= last, r ^= last;
if (l > r) swap(l, r);
last = query(l, r);
printf("%d\n", last);
}
return 0;
}