比赛 20160415x 评测结果 AAAAAAATAAAAAAAATTTA
题目名称 数字查询 最终得分 80
用户昵称 debug 运行时间 21.167 s
代码语言 C++ 内存使用 3.38 MiB
提交时间 2016-04-15 16:22:56
显示代码纯文本
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
using namespace std;
struct ff{int x,y,num;}f[55555]={},g[55555]={};
bool cmp1(ff m,ff n){return m.x<n.x;}int h[55555]={};
bool cmp2(ff m,ff n){return m.num<n.num;}int ans=0;//明显要先离散化
int l,r;int cnt[55555]={};int n,m;//分成两部分,只出现一次的部分和出现超过一次的部分,这样进行暴力明显快了不少,出现一次的那些数字可以用线段树
bool vis1[55555]={},vis2[55555]={};//vis1==只出现一次的那些数字,vis2==只出现一次的数字所在的位置
int gug=1;int tree[272222]={};int top;//数字最大为top,下标最大为n
int next1[55555]={},next2[55555]={};
int findd(int a,int b,int c,int d,int e)
{
	if(a==c&&b==d)
		return tree[e];
	int zhong=c+d>>1;
	if(b<=zhong)
		return findd(a,b,c,zhong,e*2);
	if(a>zhong)
		return findd(a,b,zhong+1,d,e*2+1);
	return min(findd(a,zhong,c,zhong,e*2),findd(zhong+1,b,zhong+1,d,e*2+1));
}
void lisanhua()
{
	sort(f+1,f+n+1,cmp1);
	f[1].y=1;
	for(int i=2;i<=n;i++)
		if(f[i].x==f[i-1].x)
			f[i].y=f[i-1].y;
		else
			f[i].y=f[i-1].y+1;
	for(int i=1;i<=n;i++)
		h[f[i].y]=f[i].x;
	top=f[n].y;
	sort(f+1,f+1+n,cmp2);
}
void codeforces()
{
	for(int i=1;i<=n;i++)
		cnt[f[i].y]++;
	for(int i=1;i<=n;i++)
		if(cnt[f[i].y]==1)
			vis2[i]=1,vis1[f[i].y]=1;
	next1[top]=top+1,next2[n]=n+1;
	for(int i=top-1;i>=0;i--)
		if(vis1[i+1])
			next1[i]=next1[i+1];
		else
			next1[i]=i+1;
	for(int i=n-1;i>=0;i--)
		if(vis2[i+1])
			next2[i]=next2[i+1];
		else
			next2[i]=i+1;
	for(int i=1;i<=n;i++)
		if(cnt[f[i].y]==1)
			tree[i+gug-1]=f[i].y;
	for(int i=gug-1;i>0;i--)
		tree[i]=min(tree[i*2],tree[i*2+1]);
	for(int i=1;i<=n;i++)
		cnt[i]=0;
	return;
}
void slove(int s,int t)
{
	for(int i=next1[0];i<=top;i=next1[i])
		cnt[i]=0;
	for(int i=next2[s-1];i<=t;i=next2[i])
		cnt[f[i].y]++;
	int maxx=0;int weizhi=2147483647;
	for(int i=next1[0];i<=top;i=next1[i])
		if(maxx<cnt[i])
			maxx=cnt[i],weizhi=i;
	if(maxx<=1)
		weizhi=min(weizhi,findd(s,t,1,gug,1));
	ans=h[weizhi];
}
int main()
{
	freopen("numquery.in","r",stdin);
	freopen("numquery.out","w",stdout);
	scanf("%d%d",&n,&m);
	while(gug<n)gug<<=1;
	for(int i=1;i<=gug*2;i++)
		tree[i]=2147483647;
	for(int i=1;i<=n;i++)
		scanf("%d",&f[i].x),f[i].num=i;
	lisanhua();
	for(int i=1;i<=m;i++)
		scanf("%d%d",&g[i].x,&g[i].y);
	codeforces();
	for(int i=1;i<=m;i++)
	{
		l=(g[i].x+ans-1)%n+1;
		r=(g[i].y+ans-1)%n+1;
		if(l>r)swap(l,r);
		slove(l,r);
		printf("%d\n",ans);
	}
	return 0;
}