BZOJ2724 蒲公英


题目背景

亲爱的哥哥:

你在那个城市里面过得好吗?

我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的……

最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢!

哥哥你要快点回来哦!

爱你的妹妹 Violet

Azure 读完这封信之后微笑了一下。

“蒲公英吗……”

题目描述

在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。

为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 (a1,a2..an)" role="presentation">(a1,a2..an)(a1,a2..an)其中 ai" role="presentation">aiai为一个正整数,表示第i棵蒲公英的种类编号。

而每次询问一个区间 [l,r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。

注意,你的算法必须是在线的

输入输出格式

输入格式:

第一行两个整数 n,m ,表示有n株蒲公英,m 次询问。

接下来一行n个空格分隔的整数 ai" role="presentation">aiai ,表示蒲公英的种类

再接下来m 行每行两个整数 l0,r0" role="presentation">l0,r0l0,r0 ,我们令上次询问的结果为 x(如果这是第一次询问, 则 x=0)。

令l=(l0+x−1)modn+1,r=(r0+x−1)modn+1" role="presentation">l=(l0+x−1)modn+1,r=(r0+x−1)modn+1l=(l0+x−1)modn+1,r=(r0+x−1)modn+1 ,如果 l>r,则交换 l,r 。

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

输出格式:

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

输入输出样例

输入样例#1

6 3

1 2 3 2 1 2

1 5

3 6

1 5

输出样例#1:

1

2

1

说明

对于 20% 的数据,保证 1≤n,m≤30001≤n,m≤3000" role="presentation">1≤n,m≤30001≤n,m≤30001≤n,m≤30001≤n,m≤3000。

对于 100% 的数据,保证 1≤n≤40000,1≤m≤50000,1≤ai≤109" role="presentation">1≤n≤40000,1≤m≤50000,1≤ai≤1091≤n≤40000,1≤m≤50000,1≤ai≤109


区间求众数

分块

cnt[i][j]" role="presentation">cnt[i][j]cnt[i][j]表示第i个数在前j个块中的数量

ans[i][j]" role="presentation">ans[i][j]ans[i][j]表示第i到第j个块中的众数

先离散,然后预处理cnt" role="presentation">cntcnt和ans" role="presentation">ansans,对于查询,先把答案设定为完整块的众数,不是完整块的部分就暴力枚举进行比较好了

时间&空间效率O(nsqrt(n))" role="presentation">O(nsqrt(n))O(nsqrt(n))


#include<bits/stdc++.h>
using namespace std;
#define N 210
#define M 40010
#define For(x,a,b) for(int x=a;x<=b;x++)
map<int,int> mp;
int n,m,tot=0,lastans=0;
int a[M],b[M],pre[M],t[N]={0};
int block[M],L[N],R[N];
int cnt[M][N]={0},ans[N][N]={0};
int calc(int id,int lb,int rb){
return cnt[id][rb]-cnt[id][lb-1];
}
void init(){
int siz=sqrt(n);
For(i,1,n)block[i]=(i-1)/siz+1;
int bsiz=block[n];
For(i,1,bsiz)L[i]=R[i-1]+1,R[i]=min(n,i*siz);
For(i,1,n)cnt[b[i]][block[i]]++;
For(i,1,tot)For(j,1,bsiz)cnt[i][j]+=cnt[i][j-1];
For(i,1,bsiz)
For(j,i,bsiz){
int tmp=ans[i][j-1];
For(k,L[j],R[j]){
int t1=calc(b[k],i,j),t2=calc(tmp,i,j);
if((t1==t2&&pre[b[k]]<pre[tmp])||t1>t2)tmp=b[k];
}
ans[i][j]=tmp;
}
}
bool check(int id,int tmp){
if(t[id]>t[tmp])return 1;
if(t[id]==t[tmp]&&pre[id]<pre[tmp])return 1;
return 0;
}
int solve(int l,int r){
int pl=block[n]+1,pr=0;
For(i,1,block[n])if(L[i]>=l)pl=min(pl,i);
For(i,1,block[n])if(R[i]<=r)pr=max(pr,i);
if(pl>pr){
int tmp=0;
For(i,l,r)t[b[i]]=0;
For(i,l,r)t[b[i]]++;
For(i,l,r)if(check(b[i],tmp))tmp=b[i];
return tmp;
}
int tmp=ans[pl][pr];
t[tmp]=calc(tmp,pl,pr);
For(i,l,L[pl]-1)t[b[i]]=calc(b[i],pl,pr);
For(i,R[pr]+1,r)t[b[i]]=calc(b[i],pl,pr);
For(i,l,L[pl]-1)t[b[i]]++;
For(i,R[pr]+1,r)t[b[i]]++;
For(i,l,L[pl]-1)if(check(b[i],tmp))tmp=b[i];
For(i,R[pr]+1,r)if(check(b[i],tmp))tmp=b[i];
return tmp;
}
int main(){
scanf("%d%d",&n,&m);
For(i,1,n){
scanf("%d",&a[i]);
if(!mp.count(a[i])){
mp[a[i]]=++tot;
pre[tot]=a[i];
}
b[i]=mp[a[i]];
}
init();
For(i,1,m){
int l,r;scanf("%d%d",&l,&r);
l=(l+lastans-1)%n+1;
r=(r+lastans-1)%n+1;
if(l>r)swap(l,r);
lastans=pre[solve(l,r)];
printf("%d\n",lastans);
}
return 0;
}

BZOJ2724 蒲公英 【分块】的更多相关文章

  1. [日常摸鱼]bzoj2724蒲公英-分块

    区间众数经典题~ http://begin.lydsy.com/JudgeOnline/problem.php?id=4839这里可以提交~ 题意大概就是没有修改的询问区间众数,如果有一样的输出最小的 ...

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

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

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

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

  4. 【bzoj2724】[Violet 6]蒲公英 分块+STL-vector

    题目描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 样例输入 6 3 1 2 3 2 1 2 1 5 3 ...

  5. BZOJ2724 [Violet]蒲公英 分块

    题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ...

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

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

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

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

  8. [Violet]蒲公英 分块

    发现写算法专题老是写不动,,,, 所以就先把我在luogu上的题解搬过来吧! 题目大意:查询区间众数,无修改,强制在线 乍一看是一道恐怖的题,仔细一看发现并没有那么难: 大致思路是这样的,首先我们要充 ...

  9. [BZOJ2724] 蒲公英

    题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了.我觉得把那么可怕 ...

随机推荐

  1. 通过SSH key获取GitHub上项目,导入到IDEA中

    1.在Windows上安装Git 在Windows上使用Git,可以从Git官网直接下载安装程序,然后按默认选项安装即可 安装完成后,在开始菜单里找到“Git”->“Git Bash”,或者在文 ...

  2. Java循环语句之 while

    生活中,有些时候为了完成任务,需要重复的进行某些动作.如参加 10000 米长跑,需要绕 400 米的赛道反复的跑 25 圈.在 Java 中实现功能时,也经常需要重复执行某些代码,例如,我们为了表示 ...

  3. Delphi.format填充0

    1. ]);// 一共8位数字不够的补零 2. 3. 4. 5.

  4. python调用虹软2.0(全网首发)-更新中

    python调用虹软2.0目前没有任何demo可以参考,自己研究了2个晚上终于把第一步做出来了,使用了opencv来加载和显示图片,龟速更新中 这一版作废,新版已发出:https://www.cnbl ...

  5. MySQL表类型MyISAM/InnoDB的区别(解决事务不回滚的问题)

    MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与 ...

  6. Eclipse中快速定位

    Eclipse中快速定位 选中项目,ctrl+h 一.目标 查找如下的页面属于哪个activity 二.步骤 1.查找关键字 上述页面中“点我”两个字比较显眼,我们可以去android项目中搜索出现“ ...

  7. spring mvc: rss(xml)输出

    准备: rss包插件 Rome 库及其依赖项rome-utils,jdom和slf4j <!-- rss源依赖 --> <!-- https://mvnrepository.com/ ...

  8. 设计模式--门面模式C++实现

    门面模式C++实现 1定义facade 要求一个子系统的外部接口与其内部的通信必须通过一个统一的接口进行.门面模式提供一个高层次的接口,使得子系统更容易视同 注:门面模式注重统一对象,也就是提供一个访 ...

  9. 启用/禁用以太网的批处理,用于一个网卡切换本地网络和wifi使用(Win10)

    注意下面时英文版上默认网络使用,同时接入了网线和wifi时,本地网络优先wifi. 所以禁用本地网络就会自动连接到wifi,启用本地网络,就会禁用wifi. 批处理支持 -y 参数,跳过用户输入y,代 ...

  10. IOS UI-控制器的生命周期

    一.控制器的生命周期 代码 @interface NJOneViewController () @property (nonatomic, strong) NSArray *foods; @end @ ...