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. url传递数据类型

    php中传递数据,get或post方式为啥用字符串传递,为什么不能直接用数组形式,用的话可以吗

  2. MySQL索引最左原则

    通过实例理解单列索引.多列索引以及最左前缀原则 实例:现在我们想查出满足以下条件的用户id: 因为我们不想扫描整表,故考虑用索引. 单列索引: ALTER TABLE people ADD INDEX ...

  3. bootstrap系统学习

    1.响应式中注意的内容: 一行(row)必须在.container中. col-xs- col-sm- col-md- col-lg- 列偏移 .col-md-offset-* 列排序 .col-md ...

  4. Django框架数据库模型

    博主最近开始优化之前的API接口自动化框架,这次打算使用django框架来完成 # -*- coding: utf-8 -*- from __future__ import unicode_liter ...

  5. git-----初始化配置添加用户名和密码

    Git是分布式版本控制系统,GitHub 是最大的 Git 版本库托管商,是成千上万的开发者和项目能够合作进行的中心. 大部分 Git 版本库都托管在 GitHub,很多开源项目使用 GitHub 实 ...

  6. python 数组中如何根据值,获取索引,如何根据索引删除值 , 以及如何根据值删除值

    假设有一数组 s = [1,2,3,4,5,6,7,8,9] (1)如何根据值获取索引 ,如果值为5 , 那对应的索引为? (2)如何根据索引删除值 , 删除数组中索引5对应的值: (3)根据数组中的 ...

  7. ffmpeg播放RTSP的一点优化

    简单记录一下最近使用ffmpeg播放RTSP做的一点参数优化. 先做如下定义: AVDictionary* options = NULL; 1.画质优化 原生的ffmpeg参数在对1920x1080的 ...

  8. UVA-1623 Enter The Dragon (贪心)

    题目大意:有n个装满水的湖,m天.每天可能下雨也可能晴天,只要下雨就会把湖填满,若已满,则发洪水.有一台只能在晴天使用的抽水机,每次抽水只能抽一个湖,并且全部抽光.问是否存在一种使得不发洪水的抽水方案 ...

  9. 【转】 JavaScript:history.go() 的妙用(转) 处理post回发后返回

    在Web开发中,会遇到从一页(父页)导向另一页(子页),并且要求“返回”父页的情况,在这里如果用ASP.NET提供的 Response.Redirect()方法,往往不会达到理想的效果,例如:返回后, ...

  10. nyoj164——卡特兰数(待填坑)

    题意:将1~2n个数按照顺时针排列好,用一条线将两个数字连接起来要求:线之间不能有交点,同一个点只允许被连一次. 最后问给出一个n,有多少种方式满足条件. 卡特兰数(列): 令h(0)=1,h(1)= ...