简单分块求条
查看原帖
简单分块求条
1348260
Eterna楼主2024/12/2 19:27

WA+RE

和题解对拍也没有错。

#include<bits/stdc++.h>
#define int long long
#define rd read()
#define gc getchar()//pa == pb && (pb = (pa = buf) + fread(buf, 1, 100000, stdin), pa == pb) ? EOF : *pa++
#define N 500005
using namespace std;
static char buf[100000], * pa(buf), * pb(buf);
inline int read()
{
	register unsigned int x=0,s=gc;
	while(s<'0'||s>'9')s=gc;
	while(s>='0'&&s<='9')x=(x<<3)+(x<<1)+(s^48),s=gc;
	return x;
}
int n,m,block,C=0;
int A[N],a[N],tot;
int f[805][805],d[805][805],s;
int L[805],R[805],cnt[N];
int pos[805],bl[N],ans=0;
vector<int> v[N];
int qr(int l,int r)
{
	int res=0;
	if(bl[l]==bl[r]) 
	{
    	for(register int i=l;i<=r;i++)cnt[a[i]]=0;
    	for(register int i=l;i<=r;i++)res=max(res,++cnt[a[i]]);
    	return res;
  	} 
	res=f[bl[l]+1][bl[r]-1];
  	for(register int i=l;bl[i]==bl[l];i++)while(pos[i]+res<v[a[i]].size()&&v[a[i]][pos[i]+res]<=r)++res;
  	for(register int i=r;bl[i]==bl[r];i--)while(pos[i]>=res&&v[a[i]][pos[i]-res]>=l)++res;
  	return res;
}
signed main()
{
	n=rd,m=rd;block=sqrt(n);tot=n/block;
	if(n%block)tot++;
	for(register int i=1;i<=n;++i)A[i]=a[i]=rd,bl[i]=(i-1)/block+1;
	sort(A+1,A+n+1);
    register int uni=unique(A+1,A+n+1)-A-1;
    for(register int i=1;i<=n;++i)a[i]=lower_bound(A+1,A+uni+1,a[i])-A;
	for(int i=1;i<=tot;i++)L[i]=R[i-1]+1,R[i]=i*block;
	R[tot]=n;
    for(int i=1;i<=n;i++)v[a[i]].emplace_back(i),pos[i]=v[a[i]].size()-1;
    for(int i=1;i<=tot;i++)
    {
    	memset(cnt,0,sizeof(cnt));
    	for(int j=i;j<=tot;j++)
    	{
    		f[i][j]=f[i][j-1];
    		for(int k=L[j];k<=R[j];k++)f[i][j]=max(f[i][j],++cnt[a[k]]);
		}
	}
	while(m--)
	{
		int l=rd^ans,r=rd^ans;
		if(l>r)swap(l,r);
		cout<<(ans=qr(l,r))<<'\n';
	}
	return 0;
} 
2024/12/2 19:27
加载中...