原文链接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]蒲公英 分块的更多相关文章

  1. bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式

    这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...

  2. [BZOJ2724][Violet 6]蒲公英

    [BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...

  3. 【BZOJ2724】[Violet 6]蒲公英 分块+二分

    [BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...

  4. BZOJ 2724: [Violet 6]蒲公英( 分块 )

    虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ...

  5. 【分块】bzoj2724 [Violet 6]蒲公英

    分块,离散化,预处理出: ①前i块中x出现的次数(差分): ②第i块到第j块中的众数是谁,出现了多少次. 询问的时候,对于整块的部分直接获得答案:对于零散的部分,暴力统计每个数出现的次数,加上差分的结 ...

  6. bzoj2724: [Violet 6]蒲公英(分块)

    传送门 md调了一个晚上最后发现竟然是空间开小了……明明算出来够的…… 讲真其实我以前不太瞧得起分块,觉得这种基于暴力的数据结构一点美感都没有.然而今天做了这道分块的题才发现分块的暴力之美(如果我空间 ...

  7. 【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 ...

  8. bzoj2724: [Violet 6]蒲公英(离散化+分块)

    我好弱啊..这题调了2天QwQ 题目大意:给定一个长度为n(n<=40000)的序列,m(m<=50000)次询问l~r之间出现次数最多的数.(区间众数) 这题如果用主席树就可以不用处理一 ...

  9. BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]

    传送门 题面太美不忍不放 分块分块 这种题的一个特点是只有查询,通常需要预处理:加入修改的话需要暴力重构预处理 预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][ ...

随机推荐

  1. eclipse:显示堆内存

    如下图 :

  2. Android来电拦截及来电转移

    1. 电话拦截这个功能大家可能都知道了,就是利用反射原理调用ITelephony的隐藏方法来实现.这个就不说了,在附件的代码里有.2.拦截后提示忙音/空号/已关机/已停机这个功能其实是要用到MMI指令 ...

  3. JetBrains GoLand 2018 激活码/ 注册码(最新破解方法)

    1 前言 本机测试环境如下: Goland版本:2018.1.5 电脑系统:win7 64位 JetbrainsCrack.jar:链接: https://pan.baidu.com/s/1blmN3 ...

  4. 关于Sublime text 3如何编辑less并转(编译)成css文件

    今天开始学习使用less这个强大方便的前端工具,本来是考虑用koala(专门编辑less的软件)来使用less的,但是发现sublime编辑器也可以实现对less的编译及高亮显示代码,这样既能少用一个 ...

  5. JSP概述

    一.JSP页面本质上时一个Servlet,然而,用JSP开发比使用Servlet更容易,主要有两个原因,首先不必编译Servlet,其次JSP页面是一个以.jsp为扩展名的文本文件,可以使用任何编辑器 ...

  6. cf1051d 简单的状态压缩dp

    /* 给定一个二行n列的格子,在里面填黑白色,要求通过黑白色将格子分为k块 请问有多少种填色方式 dp[j][k][0,1,2,3] 填到第j列,有k块,第j列的颜色, */ #include< ...

  7. Gson将字符串转map时,int默认为double类型

      gson能够将json字符串转换成map, 但是在转成map时, 会默认将字符串中的int , long型的数字, 转换成double类型 , 数字会多一个小数点 , 如 1 会转成 1.0 Gs ...

  8. Docker 快速删除所有容器

    查看运行容器 docker ps 查看所有容器 docker ps -a 进入容器 其中字符串为容器ID: docker exec -it d27bd3008ad9 /bin/bash 1.停用全部运 ...

  9. java设置字符串编码、转码

    Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一 ...

  10. 论文阅读笔记二十六:Fast R-CNN (ICCV2015)

    论文源址:https://arxiv.org/abs/1504.08083 参考博客:https://blog.csdn.net/shenxiaolu1984/article/details/5103 ...