分块离奇 RE 求调
查看原帖
分块离奇 RE 求调
482728
Engulf楼主2022/7/18 16:51

思路参考 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;
}
2022/7/18 16:51
加载中...