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][ ...
随机推荐
- js浏览器判断函数
function userBrowser(){ var browserName=navigator.userAgent.toLowerCase(); if(/msie/i.test(browserNa ...
- tomcat占用cpu比较多
在Linux中当Tomcat启动后,我们只是去查看应用是否能够正常访问来判断Tomcat启动是否正常.一般情况下这样看是没有问题的,但是有时候我们会发现当Tomcat使用了一段时间后,开始出现CPU或 ...
- python之hashlib
简介: 用于加密相关的操作,代替了md5模块和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法.在python3中已经废弃了md5和sha模块,简单说明 ...
- python深浅拷贝与赋值
初学编程的小伙伴都会对于深浅拷贝的用法有些疑问,今天我们就结合python变量存储的特性从内存的角度来谈一谈赋值和深浅拷贝~~~ 预备知识一——python的变量及其存储 在详细的了解python中赋 ...
- centos6.5磁盘扩容
3台虚拟机都是20G磁盘,用着用着发现不够了,先扩容了一台,各种百度...各种坑,每个人的情况不一样,发现不一样的地方最后立即百度查看.一台扩容成功后,打算再扩容一台,目的是留一个记录.(我是用xsh ...
- mabytis的xml一些写法
1.jdbcType=TIMESTAMP 而不是 jdbcType=DATETIME myabtis 3.4.6 版本jar包中:jdbcType枚举: ARRAY(Types.ARRAY), BIT ...
- Confluence 6 重构 ancestor 表
ancestor 表记录了上级和下级(子页面)页面之间的关系.这个表格同时被用来确定子页面是否具有从上级页面继承来的限制(restrictions)权限. 偶尔 ancestor 表格中的数据可能被损 ...
- Confluence 6 附件存储提取文本文件
当基于文本的文件上传到 Confluence(例如,Word,PowerPoint 等),这些文件中的文本是可以提取并且添加到索引中的,用户可以通过索引来搜索这些文件中的文本内容,不仅仅是搜索文件名. ...
- Confluence 6 其他需要备份和恢复的地方
XML 备份被描述用于在 Confluence 备份使用的其他方法,例如升级和移动服务器.使用上面描述的备份和恢复方法也适用这些地方. 我们的 upgrade guide 不要求使用一个 XML 备份 ...
- 拓扑排序基础 hdu1258,hdu2647
由这两题可知拓扑排序是通过“小于”关系加边建图的 hdu2647 /* 拓扑排序的原则是把“小于”看成有向边 此题反向建图即可 并且开num数组来记录每个点的应该得到的权值 */ #include&l ...