【BZOJ2724】蒲公英(分块)
【BZOJ2724】蒲公英(分块)
题面
洛谷
谴责权限题的行为
题解
分块什么的都不会,根本就没写过几次。
复杂度根本不会分析,吓得我赶快来练练。
这题要求的是区间众数,显然没有什么很好的主席树之类的方法。
再加之这个数据范围很像\(O(n\sqrt n)\),所以我们来分块,假设块大小为\(\sqrt n\)。
首先颜色什么的直接离散是没有任何问题的。
那么我们可以考虑分块之后对于每一个颜色在块内的出现次数维护一个前缀和,但是这样子仍然无法快速得出一个颜色在某特定区间的出现次数。所以我们对于每一个颜色维护一个\(vector\),把所有出现的位置按照顺序压进来,这样子每次二分即可。
考虑区间众数是怎么产生的,要么是中间连续整块的众数,要么是区间左右两侧非整块的区间中出现过的数字。
中间连续整块的众数可以预处理,设\(g[i][j]\)表示第\(i\)块到第\(j\)块的众数,显然这个可以固定左端点,然后向右端点推进预处理结果。
对于非整块区间出现的位置,因为最多只会有\(2\sqrt n\)个,所以可以对于每一个数字暴力二分一遍,这样子的复杂度是\(O(\sqrt nlogn)\)的。
看起来复杂度就很对了?\(O(n\sqrt n logn)\),似乎块大小不取\(\sqrt n\)而是取别的值的时候更优秀。(尝试了一堆值,从\(200\)取到了\(20\),发现取\(30\)的时候最优)
我代码常数比较大。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 40040
const int m=30;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,Q,blk,a[MAX],b[MAX];
int S[MAX],tot,num[MAX];
vector<int> p[MAX];
int f[1500][1500];
int Calc(int x,int l,int r)
{
if(p[x].size()==0)return 0;
int L,R,ret1,ret2;
L=0,R=p[x].size()-1,ret1=R;
while(L<=R)
{
int mid=(L+R)>>1;
if(p[x][mid]>=l)ret1=mid,R=mid-1;
else L=mid+1;
}
L=0,R=p[x].size()-1,ret2=L;
while(L<=R)
{
int mid=(L+R)>>1;
if(p[x][mid]<=r)ret2=mid,L=mid+1;
else R=mid-1;
}
return max(ret2-ret1+1,0);
}
int main()
{
n=read();Q=read();blk=(n+m-1)/m;
for(int i=1;i<=n;++i)S[i]=a[i]=read();
sort(&S[1],&S[n+1]);tot=unique(&S[1],&S[n+1])-S-1;
for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[tot+1],a[i])-S;
for(int i=1;i<=n;++i)p[a[i]].push_back(i);
for(int i=1;i<=n;++i)b[i]=(i-1)/m+1;
for(int i=1;i<=blk;++i)
{
memset(num,0,sizeof(num));
int x=0;
for(int k=i;k<=blk;++k)
{
for(int j=(k-1)*m+1;j<=n&&j<=k*m;++j)
{
num[a[j]]++;
if(num[a[j]]>num[x]||(num[a[j]]==num[x]&&x>a[j]))x=a[j];
}
f[i][k]=x;
}
}
int ans=0;
while(Q--)
{
int l=(read()+ans-1)%n+1,r=(read()+ans-1)%n+1;
if(l>r)swap(l,r);
int mx=0,x=0;
if(b[l]==b[r])
for(int i=l;i<=r;++i)
{
int d=Calc(a[i],l,r);
if(d>mx||(d==mx&&x>a[i]))mx=d,x=a[i];
}
else
{
x=f[b[l]+1][b[r]-1];mx=Calc(x,l,r);
for(int i=l;i<=n&&(i==l||i%m!=1);++i)
{
int d=Calc(a[i],l,r);
if(d>mx||(d==mx&&x>a[i]))mx=d,x=a[i];
}
for(int i=r;i>=1&&(i==r||i%m!=0);--i)
{
int d=Calc(a[i],l,r);
if(d>mx||(d==mx&&x>a[i]))mx=d,x=a[i];
}
}
printf("%d\n",ans=S[x]);
}
return 0;
}
【BZOJ2724】蒲公英(分块)的更多相关文章
- [日常摸鱼]bzoj2724蒲公英-分块
区间众数经典题~ http://begin.lydsy.com/JudgeOnline/problem.php?id=4839这里可以提交~ 题意大概就是没有修改的询问区间众数,如果有一样的输出最小的 ...
- BZOJ2724 蒲公英 【分块】
BZOJ2724 蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被 ...
- 【BZOJ2724】[Violet 6]蒲公英 分块+二分
[BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...
- BZOJ2724 [Violet 6]蒲公英 分块
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ...
- 【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 ...
- BZOJ2724 [Violet]蒲公英 分块
题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ...
- bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式
这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...
- BZOJ 2724: [Violet 6]蒲公英( 分块 )
虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...
- [Violet]蒲公英 分块
发现写算法专题老是写不动,,,, 所以就先把我在luogu上的题解搬过来吧! 题目大意:查询区间众数,无修改,强制在线 乍一看是一道恐怖的题,仔细一看发现并没有那么难: 大致思路是这样的,首先我们要充 ...
- [BZOJ2724] 蒲公英
题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了.我觉得把那么可怕 ...
随机推荐
- 【转载】pycharm常用快捷键
来源: (https://blog.csdn.net/weixin_41059146/article/details/78826163) 1.编辑(Editing) Ctrl + Space 基 ...
- linux一切皆文件之文件描述符(一)
一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件.如:普通文件.目录.字符设备.块设备.套接字等 2.当一个文件被进程打开,就会创建一个文件描述符.这时候,文件的路径就 ...
- GlusterFS分布式存储集群-1. 部署
参考文档: Quick Start Guide:http://gluster.readthedocs.io/en/latest/Quick-Start-Guide/Quickstart/ Instal ...
- LeetCode-63.不同路径Ⅱ
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 现在考虑网 ...
- Doing Homework again:贪心+结构体sort
Doing Homework again Problem Description Ignatius has just come back school from the 30th ACM/ICPC. ...
- 【RL系列】马尔可夫决策过程中状态价值函数的一般形式
请先阅读上一篇文章:[RL系列]马尔可夫决策过程与动态编程 在上一篇文章里,主要讨论了马尔可夫决策过程模型的来源和基本思想,并以MAB问题为例简单的介绍了动态编程的基本方法.虽然上一篇文章中的马尔可夫 ...
- [转] Unicode字符编码区间表
firebug 打UTF8 字符: var res = ""; for(var i=0x80;i< 0xff ;i++){ res += i.toString(16) + & ...
- JVM新生代老年代详解
1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...
- Scrum Meeting 10.26
1.会议内容 姓名 今日任务 明日任务 预估时间(h) 徐越 学习服务器配置 配置SQLserver 4 卞忠昊 阅读代码 找上届代码的bug 3 武鑫 查阅资料 查阅资料,各种app的界面设计 3 ...
- 2-First scrum meeting-20151201
前言 因为编译和数据库的影响,这学期的担子差点抗不起来……所以在老师的同情之下我们的第二阶段从今天开始正式开工.因为scrum meeting要求更新,所以配合其他作业,完成功能可能细化到模块部分. ...