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][ ...
随机推荐
- Metrics介绍和Spring的集成
参考: http://colobu.com/2014/08/08/Metrics-and-Spring-Integration/ https://www.cnblogs.com/yangecnu/p/ ...
- python-时间模块,random、os、sys、shutil、json和pickle模块
一.time与datetime模块 time模块: 时间戳:表示的是从1970年1月1日00:00:00开始按秒计算的偏移量,返回类型为float类型 格式化时间字符串(Format String) ...
- Python下划线的详解
本文将讨论Python中下划线(_)字符的使用方法.我们将会看到,正如Python中的很多事情,下划线的不同用法大多数(并非所有)只是常用惯例而已. 单下划线(_) 通常情况下,会在以下3种场景中使用 ...
- Confluence 6 如何配置快速导航的同时查找数量
进入后台后查看快速导航的启用和可以同时查找的数量. 然后进行通过单击右上角的编辑(Edit)按钮进行编辑. 对配置进行配置,启用快速查询和可以同时使用的最大查询数量. https://www.cwik ...
- JS实现的ajax和同源策略
一.回顾jQuery实现的ajax 首先说一下ajax的优缺点 优点: AJAX使用Javascript技术向服务器发送异步请求: AJAX无须刷新整个页面: 因为服务器响应内容不再是整个页面,而是页 ...
- LeetCode(114): 二叉树展开为链表
Medium! 题目描述: 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解题思路: 这 ...
- 广工赛-hdu6468构造十叉树
是个以前没见过的模板题.. 我用比较复杂度方式过掉了.. 构造一个十叉树(有点trie的味道)来存数字,然后字典序就是先序遍历的结果 #include<bits/stdc++.h> usi ...
- 高斯消元处理无解|多解情况 poj1830
高斯消元结束后,若存在系数为0,常数不为0的行,则方程无解 若系数不为0的行有k个,则说明主元有k个,自由元有n-k个,方程多解 /* 给定n个开关的初始状态si,要求将其变成目标状态di 规定: 每 ...
- uva11426 欧拉函数应用,kuangbin的筛法模板
/* 给定n,对于所有的对(i,j),i<j,求出sum{gcd(i,j)} 有递推式sum[n]=sum[n-1]+f[n] 其中f[n]=gcd(1,n)+gcd(2,n)+gcd(3,n) ...
- MySQL5.7版本及以上,改密码sql语句;grant创建用户已经密码
mysql> update mysql.user set authentication_string = password('*****') where user = 'root'; gran ...