【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】蒲公英(分块)的更多相关文章

  1. [日常摸鱼]bzoj2724蒲公英-分块

    区间众数经典题~ http://begin.lydsy.com/JudgeOnline/problem.php?id=4839这里可以提交~ 题意大概就是没有修改的询问区间众数,如果有一样的输出最小的 ...

  2. BZOJ2724 蒲公英 【分块】

    BZOJ2724 蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被 ...

  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. BZOJ2724 [Violet 6]蒲公英 分块

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ...

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

  6. BZOJ2724 [Violet]蒲公英 分块

    题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ...

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

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

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

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

  9. [Violet]蒲公英 分块

    发现写算法专题老是写不动,,,, 所以就先把我在luogu上的题解搬过来吧! 题目大意:查询区间众数,无修改,强制在线 乍一看是一道恐怖的题,仔细一看发现并没有那么难: 大致思路是这样的,首先我们要充 ...

  10. [BZOJ2724] 蒲公英

    题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了.我觉得把那么可怕 ...

随机推荐

  1. opengl绘制三角形

    顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 索引缓冲对象:Element Buffer Object,EBO或Inde ...

  2. .Net 如何访问主流的各大数据库

    做过开发的都知道,.NET基本可以理解是和MSSQL,windows服务器属于一个好的搭档,正如PHP和MYSQL,LIUNX等也可以理解是一个完美搭配:但是在实际的开发中并不完全是这样的,如果你是学 ...

  3. 信息提示 - bootStrap4常用CSS笔记

    .alert 基类 .alert-{success.info.warning.danger.primary.secondary.light.dark} 各种类型的配色样式 .fade..show 设置 ...

  4. RHEL7 利用双网卡绑定实现VLAN

    使用nmcli创建bond配置 #nmcli connection add type bond ifname bond0 con-name bond0 mode active-backup #nmcl ...

  5. 机器学习(一):记一次k一近邻算法的学习与Kaggle实战

    本篇博客是基于以Kaggle中手写数字识别实战为目标,以KNN算法学习为驱动导向来进行讲解. 写这篇博客的原因 什么是KNN kaggle实战 优缺点及其优化方法 总结 参考文献 写这篇博客的原因 写 ...

  6. 入门向:南邮CTF_ReadAsm2_WP

    题目链接:http://ctf.nuptzj.cn/challenges#ReadAsm2 我比较菜,所以把思路全部敲上来了. 题目很明确告诉我们,这道题考察阅读汇编代码的能力. 在对编译环境和调用约 ...

  7. split命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/lkforce/article/details/71547313 Linux中的文件,特别是日志文件,特别大了不好打开,可以 ...

  8. java浮点数存储

    转自: [解惑]剖析float型的内存存储和精度丢失问题 1.小数的二进制表示问题 首先我们要搞清楚下面两个问题: (1)  十进制整数如何转化为二进制数 算法很简单.举个例子,11表示成二进制数: ...

  9. Mongodb For Mac OSX && 登录验证

    题外话:尽管有不少人贴出了 <我不用mongodb的十大理由> 等系列文章,但是 NoSQL 的发展不会因此而止步, mongodb 是 NoSQL 的典型代表,楼主还是抱乐观态度的,有人 ...

  10. php 数组去重

    php 数组去重 数组中重复项的去除 2010-07-28 15:29 一维数组的重复项: 使用array_unique函数即可,使用实例如下: <?php                    ...