【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] 蒲公英
题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了.我觉得把那么可怕 ...
随机推荐
- Java生成唯一ID
这里我用的是Java提供的java.util.UUID类来产生随机字串,UUID码是什么我就不再赘述,能满足我们的需求就可以. 下面是java代码: import java.util.UUID; pu ...
- Java SE练习题——求奇数
欢迎来到Java SE练习题频道,我是Fishing,今天我带来的练习题是(做题会有不足之处,可评论,说出更好的方法): 通过键盘输入两个整数,计算这两个整数之间的所有奇数之和,并输出计算结果. 看到 ...
- 《The Mythical Man-Month(人月神话)》读后感(1)
临近考试周,这里我通过平时阅读的<人月神话>十九个章节和知乎.简书等网页中网友们对<人月神话>的读后感,对书中各个章节进行简单的总结,以下均为个人手打观点的思考与整合,仅供大家 ...
- c++虚继承与虚函数
学习继承与多态时看到这两个概念,记录整理. 虚继承与虚函数都是用virtual关键字实现,虚继承为了防止多重继承,而虚函数为了实现多态. 是几个例子. 虚继承: class A{}; class B: ...
- Apache 性能配置优化
前言 最近在进行apache性能优化设置.在修改apache配置)文件之前需要备份原有的配置文件夹conf,这是网站架设的好习惯.以下的apache配置调优均是在red had的环境下进行的. htt ...
- fsck命令详解
基础命令学习目录首页 本文出自 “airfish2000” 博客,更多命令查看博客: http://airfish2000.blog.51cto.com/10829608/1880801 fsck ...
- Python入门学习系列——Python文件和异常
从文件中读取数据 首先准备一个文本文件,文件中存储着普通文本数据.读取文件需要调用open()和read()函数. 读取整个文件 代码示例: with open('pi_digits.txt') as ...
- Django_rest_framework_基础
简介 为什么要使用REST framework? Django REST framework 是一个强大且灵活的工具包,用以构建Web APIs. - 在线可视的API,对于赢得你的开发者们十分有用 ...
- python将response中的cookies加入到header
url = “http://abad.com”header = { "user-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64 ...
- 导出excel失败,提示提示加载类型库/DDL出错
首先,这里提供的解决办法仅适用于出现如下异常的情况:无法将类型为“Microsoft.Office.Interop.Excel.ApplicationClass”的 COM 对象强制转换为接口类型“M ...