BZOJ2724 [Violet 6]蒲公英 分块
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html
题目传送门 - BZOJ2724
题意
求区间最小众数,强制在线。
$n$ 个数,$m$ 次询问。
$n\leq 40000,m\leq 50000$
题解
看完题目:呀这不是莫队裸题吗??
再看一遍:我去怎么是强制在线!
然后经过一波思(forever)考(piano),终于会做了。
首先请你自行证明一个结论:
在询问区间内任取一段子区间,询问区间内的最小众数一定是子区间的最小众数或者出现在询问区间除掉子区间的其他地方。
于是我们考虑分块,$base=\sqrt{maxn}=200$ 一块。
我们考虑对于所有 $i,j$ 预处理出第 $i$ 块到第 $j$ 块的区间最小众数。
我还要预处理出每一个数在前 $i$ 块的出现次数 $\left(i\in \left[1,\left\lfloor\cfrac{n}{base}\right\rfloor\right]\right)$ 。
于是在询问的时候只要看一看询问区间最大连续块段的最小众数和其他剩余的数就可以了。
时间复杂度 $\Theta (n \sqrt{n})$ 。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=40005,M=205,base=200;
int n,m,hs,a[N],Ha[N],res[M][M],cnt[M][N],tax[N];
int l,r,L,R;
void HASH(){
sort(Ha+1,Ha+n+1);
hs=1;
for (int i=2;i<=n;i++)
if (Ha[i]!=Ha[i-1])
Ha[++hs]=Ha[i];
}
int calc(int x){
return tax[x]+cnt[r][x]-cnt[l][x];
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]),Ha[i]=a[i];
HASH();
for (int i=1;i<=n;i++)
a[i]=lower_bound(Ha+1,Ha+hs+1,a[i])-Ha;
memset(cnt,0,sizeof cnt);
for (int i=1;i<=base&&i*base<=n;i++)
for (int j=1;j<=i*base;j++)
cnt[i][a[j]]++;
for (int i=1;i<=base&&i*base<=n;i++){
memset(tax,0,sizeof tax);
for (int j=i;j<=base&&j*base<=n;j++){
int &Max=res[i][j];
Max=res[i][j-1];
for (int k=(j-1)*base+1,lim=j*base;k<=lim;k++){
tax[a[k]]++;
if (tax[a[k]]>tax[Max]||(tax[a[k]]==tax[Max]&&a[k]<Max))
Max=a[k];
}
}
}
memset(tax,0,sizeof tax);
int ans=0;
while (m--){
scanf("%d%d",&L,&R);
L=(L+Ha[ans]-1)%n+1,R=(R+Ha[ans]-1)%n+1;
if (L>R)
swap(L,R);
ans=0;
if (R-L+1<=base*2){
for (int i=L;i<=R;i++)
tax[a[i]]++;
for (int i=L;i<=R;i++)
if (tax[a[i]]>tax[ans]||(tax[a[i]]==tax[ans]&&a[i]<ans))ans=a[i];
for (int i=L;i<=R;i++)
tax[a[i]]--;
printf("%d\n",Ha[ans]);
continue;
}
l=(L-1)/base+1,r=R/base;
ans=res[l+1][r];
for (int i=L;i<=l*base;i++)
tax[a[i]]++;
for (int i=r*base+1;i<=R;i++)
tax[a[i]]++;
for (int i=L;i<=l*base;i++)
if (calc(a[i])>calc(ans)||(calc(a[i])==calc(ans)&&a[i]<ans))ans=a[i];
for (int i=r*base+1;i<=R;i++)
if (calc(a[i])>calc(ans)||(calc(a[i])==calc(ans)&&a[i]<ans))ans=a[i];
for (int i=L;i<=l*base;i++)
tax[a[i]]--;
for (int i=r*base+1;i<=R;i++)
tax[a[i]]--;
printf("%d\n",Ha[ans]);
}
return 0;
}
BZOJ2724 [Violet 6]蒲公英 分块的更多相关文章
- bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式
这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...
- [BZOJ2724][Violet 6]蒲公英
[BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...
- 【BZOJ2724】[Violet 6]蒲公英 分块+二分
[BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...
- BZOJ 2724: [Violet 6]蒲公英( 分块 )
虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...
- 【分块】bzoj2724 [Violet 6]蒲公英
分块,离散化,预处理出: ①前i块中x出现的次数(差分): ②第i块到第j块中的众数是谁,出现了多少次. 询问的时候,对于整块的部分直接获得答案:对于零散的部分,暴力统计每个数出现的次数,加上差分的结 ...
- bzoj2724: [Violet 6]蒲公英(分块)
传送门 md调了一个晚上最后发现竟然是空间开小了……明明算出来够的…… 讲真其实我以前不太瞧得起分块,觉得这种基于暴力的数据结构一点美感都没有.然而今天做了这道分块的题才发现分块的暴力之美(如果我空间 ...
- 【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 6]蒲公英(离散化+分块)
我好弱啊..这题调了2天QwQ 题目大意:给定一个长度为n(n<=40000)的序列,m(m<=50000)次询问l~r之间出现次数最多的数.(区间众数) 这题如果用主席树就可以不用处理一 ...
- BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]
传送门 题面太美不忍不放 分块分块 这种题的一个特点是只有查询,通常需要预处理:加入修改的话需要暴力重构预处理 预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][ ...
随机推荐
- python笔记---需求文件requirements.txt的创建及使用
/******************************************/ 感谢大家一直以来的关注与支持. 本站迁移至 http://qingkang.me 也欢迎大家继续关注. /** ...
- backtrace和backtrace_symbols
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...
- CF 489C 暴力处理
题意: 给你 数的长度 m, 数的每个数的和 Sum: 输出 这个数最小值 和最大值 #include<bits/stdc++.h> using namespace std; int ma ...
- Ex 2_3 求递推式的通项公式..._第三次作业
- 处理:“ORA-28002: the password will expire within 7 days”的问题
一:问题描述: 二:处理步骤 [oracle@localhost 2018_07_14]$ rlwrap sqlplus / as sysdba; SQL*Plus: Release 11.2.0.3 ...
- Java_oracle超出打开游标的最大数的原因和解决方案
第一步:核查Oracle数据库 的游标的最大数 处理超出打开游标的最大数异常(ORA-01000: maximum open cursors exceeded) ORA-01000_maximum_o ...
- android 使用opencv
1.将已有的项目名称改名字,但一直报错 Error:A problem occurred configuring project ':app'.> executing external nati ...
- elementui上传图片到七牛云服务器
注册七牛云 首先,注册七牛云,并且完成实名认证,完成后会在个人中心->秘钥管理中看到两个秘钥AccessKey/SecretKey 创建存储空间(必须要实名认证) 生成上传凭证 为了实现上传,我 ...
- flask 面试题
1,什么是Flask,有什么优点?概念解释Flask是一个Web框架,就是提供一个工具,库和技术来允许你构建一个Web应用程序.这个Web应用程序可以是一些Web页面,博客,wiki,基于Web的日里 ...
- kafka架构浅显理解
Kafka的概念: 1. AMQP协议 Advanced Message Queuing Protocol (高级消息队列协议) The Advanced Message Queuing Protoc ...