1. 程式人生 > >【BZOJ】【P2724】【Violet 6】【蒲公英】【題解】【分塊】

【BZOJ】【P2724】【Violet 6】【蒲公英】【題解】【分塊】

區間眾數,分塊亂搞,維護每個塊之間答案,詢問sqrt(n)logn

Code:

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=40010;
map<int,int>M;
int rM[maxn],a[maxn];
int n,m,sqrtn;
vector<int>v[maxn];
int getint(){
	int r=0;char c=getchar();
	while(!isdigit(c))c=getchar();
	while(isdigit(c))r=r*10+c-'0',c=getchar();
	return r;
}
int bel[maxn]={-1},tot,lans;
int L[maxn],R[maxn],sqrtsize;
int data[maxn];
int Anss[233][233];
int counts(int x,int l,int r){return upper_bound(v[x].begin(),v[x].end(),r)-lower_bound(v[x].begin(),v[x].end(),l);}
int Q(int l,int r){
	int l0=l,r0=r;
	bool e=bel[l]==bel[r];
	data[0]=0;
	if(e)for(int i=l;i<=r;i++)data[++data[0]]=a[i];
	if(!e)while(r!=R[bel[r]])data[++data[0]]=a[r],r--;
	if(!e)while(l!=L[bel[l]])data[++data[0]]=a[l],l++;
	int ans=233,cnt=0;
	if(!e)ans=Anss[bel[l]][bel[r]],cnt=counts(ans,l0,r0);
	sort(data+1,data+1+data[0]);
	data[0]=unique(data+1,data+1+data[0])-data-1;
	for(int i=1;i<=data[0];i++){
		int c=counts(data[i],l0,r0);
		if(c>cnt||(c==cnt&&data[i]<ans))ans=data[i],cnt=c;
	}return ans;
}
int main(){
	n=getint();m=getint();sqrtn=233;
	for(int i=1;i<=n;i++)a[i]=getint(),bel[i]=i/sqrtn;
	for(int i=1;i<=n;i++){
		if(bel[i]!=bel[i-1]){
			if(sqrtsize)R[sqrtsize-1]=i-1;
			L[sqrtsize++]=i;
		}
	}R[sqrtsize-1]=n;
	for(int i=1;i<=n;i++)M[a[i]]=1;
	for(map<int,int>::iterator it=M.begin();it!=M.end();it++)it->second=++tot;
	for(int i=1;i<=n;i++)rM[M[a[i]]]=a[i],a[i]=M[a[i]],v[a[i]].push_back(i);
	for(int i=0;i<sqrtsize;i++){
		M.clear();
		for(int j=i;j<sqrtsize;j++){
			for(int k=L[j];k<=R[j];k++)M[a[k]]++;
			int ans=0,cnt=0;
			for(map<int,int>::iterator it=M.begin();it!=M.end();it++)
			if(it->second>cnt||(it->second==cnt&&it->first<ans))ans=it->first,cnt=it->second;
			Anss[i][j]=ans;
		}
	}

	while(m--){
		// Attention!!!
		int l=(lans+getint()-1)%n+1,r=(lans+getint()-1)%n+1;
		//int l=getint(),r=getint();
		if(l>r)swap(l,r);
		lans=rM[Q(l,r)];
		printf("%d\n",lans);
	}
	return 0;
}