社区讨论

【玄关】10pts求条

P4168[Violet] 蒲公英参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@min1bgwu
此快照首次捕获于
2025/12/01 18:57
3 个月前
此快照最后确认于
2025/12/03 20:15
3 个月前
查看原帖
只 AC 了 #17,#18,其他全 WA。
分块做法,好像是块的边界问题,但找不到。
CPP
//Author: mairuisheng
//#pragma GCC optimize(3)
#include<cstdio>
#include<cmath>
#include<unordered_map>
#include<vector>
#include<algorithm>
using namespace std;
inline int read()
{
	int x=0,f=1;
	char s;
	s=getchar();
	while(s<48||s>57)
	{
		if(s=='-')f=-f;
		s=getchar();
	}
	while(s>47&&s<58)
	{
		x=(x<<3)+(x<<1)+s-48;
		s=getchar();
	}
	return x*f;
}
constexpr int N=40005;
int n,m;
int a[N],nd[N],cnt[N];
int lp[N],rp[N],pos[N],zs[N];
unordered_map<int,int> mp;
vector<int> g[N];
void Build()
{
	int i,tot=0,len=sqrt(n),res,p=0,j;
	while(rp[tot]<n)
	{
		++tot;
		lp[tot]=(tot-1)*len+1;
		rp[tot]=tot*len;
	}
	if(rp[tot]>n)rp[tot]=n;
	for(i=1;i<=n;++i)pos[i]=(i-1)/len+1;
	for(i=1;i<=tot;++i)
	{
		res=0;
		p=lp[i];
		for(j=lp[i];j<=rp[i];++j)
		{
			cnt[nd[j]]++;
			if(cnt[nd[j]]>res)
			{
				res=cnt[nd[j]];
				p=j;
			}
			else if(cnt[nd[j]]==res&&a[j]<a[p])p=j;
		}
		for(j=lp[i];j<=rp[i];++j)cnt[nd[j]]--;
		zs[i]=p;
	}
}
int Calc(int x,int l,int r)
{
	return upper_bound(g[x].begin(),g[x].end(),r)-lower_bound(g[x].begin(),g[x].end(),l);
}
int Query(int l,int r)
{
	int idl=pos[l],idr=pos[r],i,p=l,res=0,x;
	if(idl==idr)
	{
		for(i=l;i<=r;++i)
		{
			cnt[nd[i]]++;
			if(cnt[nd[i]]>res)
			{
				res=cnt[nd[i]];
				p=i;
			}
			else if(cnt[nd[i]]==res&&a[i]<a[p])p=i;
		}
		for(i=l;i<=r;++i)cnt[nd[i]]--;
		return a[p];
	}
	for(i=l;i<=rp[idl];++i)
	{
		x=Calc(nd[i],l,r);
		if(x>res)
		{
			res=x;
			p=i;
		}
		else if(x==res&&a[i]<a[p])p=i;
	}
	for(i=lp[idr];i<=r;++i)
	{
		x=Calc(nd[i],l,r);
		if(x>res)
		{
			res=x;
			p=i;
		}
		else if(x==res&&a[i]<a[p])p=i;
	}
	for(i=idl+1;i<idr;++i)
	{
		x=Calc(nd[zs[i]],l,r);
		if(x>res)
		{
			res=x;
			p=zs[i];
		}
		else if(x==res&&a[zs[i]]<a[p])p=zs[i];
	}
	return a[p];
}
int main()
{
//	freopen("P4168_1.in","r",stdin);
//	freopen("ans.out","w",stdout);
	n=read();
	m=read();
	int i,tot=0,x,l,r,ans=0;
	for(i=1;i<=n;++i)
	{
		a[i]=read();
		if(mp.count(a[i])==0)mp[a[i]]=++tot;
		x=mp[a[i]];
		nd[i]=x;
		g[x].push_back(i);
	}
	Build();
	while(m--)
	{
		l=(read()+ans-1)%n+1;
		r=(read()+ans-1)%n+1;
		if(l>r)swap(l,r);
		ans=Query(l,r);
		printf("%d\n",ans);
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...