萌新求卡常
查看原帖
萌新求卡常
376997
Harry27182SDream楼主2022/2/3 12:43

RT,卡了一上午,#3过不去,实测预处理部分 400ms,问题出在询问部分,求卡常谢谢!

#include<bits/stdc++.h>
using namespace std;
int n,q,m,l,r,x,b[500005],a[500005],block[500005],num[500005];
int bl[710],br[710],f[710][710],cnt[500005][710],ask[1420];
inline int read()
{ 
	int f=1,x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	return x*f;
}
int main()
{
	n=read();q=read();
	for(register int i=1;i<=n;++i)a[i]=b[i]=read();
	sort(b+1,b+n+1);
	m=unique(b+1,b+n+1)-b-1;
	for(register int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+m+1,a[i])-b;
	int len=sqrt(n);
	for(register int i=1;i<=n;++i)
	{
		block[i]=(i-1)/len+1;
		if(block[i]!=block[i-1])
		{
			bl[block[i]]=i;
			br[block[i-1]]=i-1;
		}
	}
	int blocks=block[n];
	bl[1]=1;br[blocks]=n;
	for(register int i=1;i<=blocks;++i)
	{
		int now=i,sum=0,pla=0;
		for(register int j=1;j<=m;j++)num[j]=0;
		for(register int j=bl[i];j<=n;j++)
		{
		    sum=max(sum,++num[a[j]]);
			if(br[now]==j)f[i][now++]=sum;
		}
	}
	int now=1;
	for(register int i=1;i<=n;++i)
	{
		cnt[a[i]][now]++;
		if(br[now]==i)
		{
			for(register int i=1;i<=m;++i)cnt[i][now+1]=cnt[i][now];
			now++; 
		}
	}
	//for(register int i=1;i<=m;++i)num[i]=0;
	while(q--)
	{
		l=read();r=read();
		l^=x;r^=x; 
		int L=block[l]+1,R=block[r]-1,tot=0;
		int ans=f[L][R];
		for(register int i=1;i<=m;++i)num[i]=0;
		for(register int i=l;i<=br[L-1];++i)if(++num[a[i]]==1)ask[++tot]=a[i];
		for(register int i=bl[R+1];i<=r;++i)if(++num[a[i]]==1)ask[++tot]=a[i];
		for(register int i=1;i<=tot;++i)ans=max(ans,num[ask[i]]+cnt[ask[i]][R]-cnt[ask[i]][L-1]);
		//for(register int i=l;i<=br[L-1];++i)ans=max(ans,num[a[i]]+cnt[a[i]][R]-cnt[a[i]][L-1]);
		//for(register int i=bl[R+1];i<=r;++i)ans=max(ans,num[a[i]]+cnt[a[i]][R]-cnt[a[i]][L-1]);
		//for(register int i=l;i<=br[L-1];++i)num[a[i]]=0;
		//for(register int i=bl[R+1];i<=r;++i)num[a[i]]=0;
		printf("%d\n",ans);x=ans;
	}
	return 0;
}
2022/2/3 12:43
加载中...