http://www.lydsy.com/JudgeOnline/problem.php?id=2724

输入格式

第一行两个整数n,m,表示有n株蒲公英,m次询问。
接下来一行 n 个空格分隔的整数ai,表示蒲公英的种类
再接下来m行每行两个整数l0,r0,我们令上次询问的结果为x(如果这是第一次询问,则x=0)。
令l=(l0+x-1)mod n +1,r=(r0+x-1)mod n +1,如果l>r,则交换l,r。

最终的询问区间为[l,r]。

输出格式

输出m行。每行一个整数,表示每次询问的结果。

样例输入

6 3
1 2 3 2 1 2
1 5
3 6
1 5

样例输出

1
2
1

——————————————————————————————————

分块板子题。

我们首先离散化,然后分块分成sqrt(N)长度的块,然后预处理一下东西:

1.sum[i][j]:前j块i元素出现次数。

2.ans[i][j]:i~j块的众数。

这两个操作都靠暴力(桶排序)解决,复杂度显然O(NsqrtN)。

然后就是惊心动魄的询问时间:

1.跨度<=2个块长度:直接暴力。

2.跨度>2个块长度:显然区间一定跨过了至少一些/个连续的块,这些连续的块的众数我们能求出来,然后我们的答案显然就是:

  1.这个众数。

  2.非整块区间内的数。

对于2暴力(桶排序)即可,然后和1比较,注意处理2的个数的时候不要忘了加上该数在连续的块中出现的个数。

简单证明:我们只需要证明非连续的块的众数的数且没出现在非整块区间内的数一定不是众数。

这十分显然,因为它本身不是非连续的块的众数,个数一定比该众数小,又没出现在非整块区间内,所以个数一定比该众数小,则它一定不可能是众数。

#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int N=;
const int SQRTN=;
const int INF=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int n,m,lim,s,cnt,a[N],b[N],bl[SQRTN],br[SQRTN];
int sum[N][SQRTN],ans[N][SQRTN],t[N];
bool vis[N];
inline void LSH(){
sort(b+,b+lim+);
lim=unique(b+,b+lim+)-b-;
for(int i=;i<=n;i++){
a[i]=lower_bound(b+,b+lim+,a[i])-b;
}
return;
}
inline void intoblock(){
for(int i=;i<=n;i++){
if(i%s==){br[cnt]=i-;bl[++cnt]=i;}
}
br[cnt]=n;bl[cnt+]=n+;
return;
}
inline void init(){
for(int i=;i<=cnt;i++){
for(int j=bl[i];j<=n;j++)t[a[j]]=;
int maxn=-INF,cur;
for(int j=i;j<=cnt;j++){
for(int k=bl[j];k<=br[j];k++){
int c=++t[a[k]];
if(c>maxn)maxn=c,cur=a[k];
else if(c==maxn&&a[k]<cur)cur=a[k];
}
ans[i][j]=cur;
}
for(int j=;j<=lim;j++)sum[j][i]=sum[j][i-];
for(int j=bl[i];j<=br[i];j++){
sum[a[j]][i]++;
}
}
return;
}
inline int query(int l,int r){
memset(vis,,sizeof(vis));
memset(t,,sizeof(t));
int maxn=-INF,cur;
if(r-l+<=*s){
for(int i=l;i<=r;i++){
vis[a[i]]=;
t[a[i]]++;
}
for(int i=l;i<=r;i++){
if(vis[a[i]]){
if(t[a[i]]>maxn)maxn=t[a[i]],cur=a[i];
else if(t[a[i]]==maxn&&a[i]<cur)cur=a[i];
}
}
return cur;
}
int L=(l-)/s+,R=(r-)/s+;
cur=ans[L+][R-];
maxn=sum[cur][R-]-sum[cur][L];
for(int i=l;i<=br[L];i++){
vis[a[i]]=;
t[a[i]]++;
}
for(int i=bl[R];i<=r;i++){
vis[a[i]]=;
t[a[i]]++;
}
for(int i=l;i<=br[L];i++){
if(vis[a[i]]){
int c=t[a[i]]+sum[a[i]][R-]-sum[a[i]][L];
if(c>maxn)maxn=c,cur=a[i];
else if(c==maxn&&a[i]<cur)cur=a[i];
}
}
for(int i=bl[R];i<=r;i++){
if(vis[a[i]]){
int c=t[a[i]]+sum[a[i]][R-]-sum[a[i]][L];
if(c>maxn)maxn=c,cur=a[i];
else if(c==maxn&&a[i]<cur)cur=a[i];
}
}
return cur;
}
int main(){
n=read();m=read();s=sqrt(n);
for(int i=;i<=n;i++)a[i]=b[++lim]=read();
LSH();
intoblock();
init();
int pre=;
for(int i=;i<=m;i++){
int l=(read()+pre-)%n+,r=(read()+pre-)%n+;
if(l>r)swap(l,r);
printf("%d\n",pre=b[query(l,r)]);
}
return ;
}

最新文章

  1. Hello bokeyuan!
  2. Python来做应用题及思路
  3. RapidJSON 代码剖析(三):Unicode 的编码与解码
  4. [BZOJ1112][POI2008]砖块Klo
  5. android studio 注释模板
  6. Java垃圾收集器之--Garbage-First Collector
  7. 安装hadoop
  8. 判断一个Bitmap图像是否是.9图
  9. C#数据类型-string
  10. Android开发笔记:安卓程序截屏方法
  11. nginx+apache+mysql+php+memcache+squid搭建集群web环境
  12. Android 调用jepg库进行图片压缩,保持图片不失真
  13. 设置SQLServer数据库内存
  14. docker必须要sudo,但是sudo的话,又获得不了环境变量怎么办?
  15. 201771010134杨其菊《面向对象程序设计java》第七周学习总结
  16. ansible的安装部署及简单应用
  17. Codeforces Round #324 (Div. 2) E
  18. Test传送门(更新中)
  19. ORA-03113:通信通道的文件结尾-完美解决方案
  20. PHP面试常用算法(推荐)

热门文章

  1. python 安装 MySQL-python
  2. Ruby 基础教程1-7
  3. 使用git bash编译安装sysbench时遇到的坑
  4. 接口测试工具postman(六)添加变量(参数化)
  5. 第一模块&#183;开发基础-第1章 Python基础语法
  6. 【Linux 运维】linux系统修改主机名
  7. 【机器学习】线性回归python实现
  8. nodejs promise深度解析
  9. selenium识别登录验证码---基于python实现
  10. HTML5 canvas制作童年的回忆大风车