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 ;
}

BZOJ2724:[Violet 6]蒲公英——题解的更多相关文章

  1. [BZOJ2724][Violet 6]蒲公英

    [BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...

  2. BZOJ2724 [Violet 6]蒲公英 分块

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ...

  3. bzoj2724: [Violet 6]蒲公英(离散化+分块)

    我好弱啊..这题调了2天QwQ 题目大意:给定一个长度为n(n<=40000)的序列,m(m<=50000)次询问l~r之间出现次数最多的数.(区间众数) 这题如果用主席树就可以不用处理一 ...

  4. bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式

    这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...

  5. 【分块】bzoj2724 [Violet 6]蒲公英

    分块,离散化,预处理出: ①前i块中x出现的次数(差分): ②第i块到第j块中的众数是谁,出现了多少次. 询问的时候,对于整块的部分直接获得答案:对于零散的部分,暴力统计每个数出现的次数,加上差分的结 ...

  6. bzoj2724: [Violet 6]蒲公英(分块)

    传送门 md调了一个晚上最后发现竟然是空间开小了……明明算出来够的…… 讲真其实我以前不太瞧得起分块,觉得这种基于暴力的数据结构一点美感都没有.然而今天做了这道分块的题才发现分块的暴力之美(如果我空间 ...

  7. 【BZOJ2724】[Violet 6]蒲公英 分块+二分

    [BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...

  8. BZOJ 2724: [Violet 6]蒲公英

    2724: [Violet 6]蒲公英 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1633  Solved: 563[Submit][Status ...

  9. BZOJ 2724: [Violet 6]蒲公英( 分块 )

    虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...

随机推荐

  1. 在Sqlserver中生成随机数据

    百度了各种随机生成,集中摘录如下: 一.循环写入千万级测试数据 DECLARE @i int ) BEGIN INSERT INTO A_User(username,password,addtime, ...

  2. css 网站常用

    简单的loading效果 .progressBar { border: solid 1px #303031; font: bold 20px/22px Arial, sans-serif; backg ...

  3. nested class 例子

    #include<iostream> using namespace std; /* start of Enclosing class declaration */ class Enclo ...

  4. InnoDB锁冲突案例演示

      Preface       As we know,InnoDB is index organized table.InnoDB engine supports row-level lock bas ...

  5. 前台时间格式 2019-03-09T16:00:00.000Z

    问题描述: 本想在前台把字符串格式的日期(2019-03-09)转换成日期格式(2019-03-09 00:00:00),但当把这个参数传到后台去后却变成了2019-03-08T16:00:00.00 ...

  6. Qt-QML-QML调用C++类

    QML用来做界面,在不考虑数据的请款下,那是溜溜的,但是,程序是没有不和后台数据交互的,但是了,QML在数据处理方面的效率又是不敢恭维的,这里就出现了QML负责前端界面,而后端使用JS或者C++了. ...

  7. 第四篇 与Flask相关的插件(flask-session、wtforms)

    公司中使用SQL的种方式: 1. 写Django:ORM(关系对象映射), 2. 写Flask和其他:有两种方式: (1) 原生SQL:使用原生SQL有两种选择: A. pymysql (python ...

  8. Python输入数据类型判断正确与否的函数大全(非常全)

      对于python输入数据类型判断正确与否的函数大致有三类: (1)type(),它的作用直接可以判断出数据的类型 (2)isinstance(),它可以判断任何一个数据与相应的数据类型是否一致,比 ...

  9. Java应用基础微专业-进阶篇

    第1章--使用对象 1.1 字符类型 char c = 65; // char --> int char c = '\u0041'; // \u: unicode + (Hex 41--> ...

  10. NHibernate3快速上手教程FluentNHibernate配置与DBHelper(已过期,有更好的)

    很多学习NHibernate的新手很容易卡在配置文件这一关,正所谓万事开头难,上手后再配合官方文档就比较容易了. 网上关于配置文件的资料非常多,但由于版本的问题,许多老的教程中都没有明确指出类库的版本 ...