回滚莫队求助
查看原帖
回滚莫队求助
464004
ZepX_D楼主2024/6/5 07:51

rt,代码基本是从模板题粘过来的,对拍无果,求 hack

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5+5;
int a[N],be[N],B,b[N],ans[N],las[N],L[N],R[N],t[N];
struct Que{int l,r,id;}q[N];

bool cmp(Que a,Que b)
{return be[a.l] == be[b.l] ? a.r < b.r : a.l < b.l;}

int W(int l,int r)
{
	int res = 0;
	for (int i = l-1;i <= r;i++) las[a[i]] = 0;
	for (int i = l-1;i <= r;i++)
		if(las[a[i]]) res = max(res,i-las[a[i]]);
		else las[a[i]] = i;
	return res;
}

int main()
{
    ios::sync_with_stdio(0);
	int n,m;cin >> n >> m;B = sqrtl(n);
	for (int i = 1;i <= n;i++)
		cin >> a[i],b[i] = (a[i] += a[i-1]),be[i] = (i-1)/B+1;
	int ct = be[n];
 	for (int i = 1;i <= m;i++)
		cin >> q[i].l >> q[i].r,q[i].id = i;
	sort(q+1,q+m+1,cmp);
	sort(b+1,b+n+1);int k = unique(b+1,b+n+1)-b-1;
	for (int i = 0;i <= n;i++)
		a[i] = lower_bound(b+1,b+k+1,a[i])-b;
	int j = 1;
	for (int i = 1;i <= ct;i++)
	{
		int ed = min(i*B,n),l = ed+1,r = ed,res = 0,cnt = 0;
		while(be[q[j].l] == i)
		{
			if(be[q[j].r] == i) ans[q[j].id] = W(q[j].l,q[j].r);
			else
			{
				while(r < q[j].r)
				{
					r++;R[a[r]] = r;
					if(!L[a[r]]) L[a[r]] = r,t[++cnt] = r;
					res = max(res,r-L[a[r]]);
				}
				int tmp = res;
				while(l >= q[j].l)
				{
					l--;
					if(!R[a[l]]) R[a[l]] = l;
					res = max(res,R[a[l]]-l);
				}
				ans[q[j].id] = res;
				while(l <= ed)
				{
					if(R[a[l]] == l) R[a[l]] = 0;
					l++;
				}
				res = tmp;
			}
			j++;
		}
		for (int k = 1;k <= cnt;k++) L[a[t[k]]] = R[a[t[k]]] = 0;
	}
	for (int i = 1;i <= m;i++)
		cout << ans[i] << '\n';
	return 0;
}
2024/6/5 07:51
加载中...