【BZOJ2724】[Violet 6]蒲公英

Description

Input

修正一下

l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1

Output

Sample Input

6 3
1 2 3 2 1 2
1 5
3 6
1 5

Sample Output

1
2
1

HINT

修正下:

n <= 40000, m <= 50000

题解:分块还是练脑子啊~

结论:一个区间的众数要么是区间中一个块的众数,要么是块外的任意一个数。

这就告诉我们需要预处理出任意两个块之间的所有数的众数,这个可以用离散化+桶+扫一遍实现。

那么对于询问[l,r]我们假设其中最大的连续的块是[ll,rr],那么我们已知了[ll,rr]中的众数,如何判断[l,ll),(rr,r]中的数是不是众数呢?

既然已经将所有数离散化了,我们就可以考虑记录每个数出现的位置。我们将每个数出现的位置从左到右用vector存起来,然后查询的时候二分一下,就知道了这个数在[l,r]中出现了多少次,用它来更新答案就行了。

sqrt(n/logn)大法好~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=40010;
int n,m,nm,B,mx,ans;
int v[maxn],st[maxn],ref[maxn];
int s[810][810];
vector<int> pos[maxn];
struct node
{
int org,val;
}num[maxn];
bool cmp(node a,node b)
{
return a.val<b.val;
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void query(int a,int b,int x)
{
if(!x||st[x]) return ;
int l=0,r=pos[x].size()-1,mid,c,d;
while(l<r)
{
mid=l+r>>1;
if(pos[x][mid]>=a) r=mid;
else l=mid+1;
}
c=r;
l=0,r=pos[x].size();
while(l<r)
{
mid=l+r>>1;
if(pos[x][mid]<=b) l=mid+1;
else r=mid;
}
d=l-1,st[x]=d-c+1;
if(st[x]>st[mx]||(st[x]==st[mx]&&x<mx)) mx=x;
}
int main()
{
//freopen("bz2724.in","r",stdin);
n=rd(),m=rd();
int i,j,a,b,c,d;
for(i=0;i<n;i++) num[i].val=rd(),num[i].org=i;
sort(num,num+n,cmp);
for(i=0;i<n;i++)
{
if(!i||num[i].val>num[i-1].val) ref[++nm]=num[i].val;
v[num[i].org]=nm;
}
B=int(sqrt(double(n)/log(n)));
for(i=0;i<n;i++) pos[v[i]].push_back(i);
for(i=0;i*B<n;i++)
{
memset(st,0,sizeof(st));
for(mx=0,j=i*B;j<n;j++)
{
st[v[j]]++;
if(st[v[j]]>st[mx]||(st[v[j]]==st[mx]&&v[j]<mx)) mx=v[j];
s[i][j/B]=mx;
}
}
memset(st,0,sizeof(st));
for(i=1;i<=m;i++)
{
a=(rd()+ans-1+n)%n,b=(rd()+ans-1+n)%n;
if(a>b) swap(a,b);
c=a/B,d=b/B;
if(c==d)
{
for(mx=0,j=a;j<=b;j++)
{
st[v[j]]++;
if(st[v[j]]>st[mx]||(st[v[j]]==st[mx]&&v[j]<mx)) mx=v[j];
}
ans=ref[mx],printf("%d\n",ans);
for(j=a;j<=b;j++) st[v[j]]--;
continue;
}
mx=0,query(a,b,s[c+1][d-1]);
for(j=a;j<c*B+B;j++) query(a,b,v[j]);
for(j=d*B;j<=b;j++) query(a,b,v[j]);
ans=ref[mx],printf("%d\n",ans);
st[s[c+1][d-1]]=0;
for(j=a;j<c*B+B;j++) st[v[j]]=0;
for(j=d*B;j<=b;j++) st[v[j]]=0;
}
return 0;
}

【BZOJ2724】[Violet 6]蒲公英 分块+二分的更多相关文章

  1. BZOJ2724 [Violet 6]蒲公英 分块

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

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

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

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

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

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

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

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

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

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

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

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

  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. LNMP第一部分环境搭建

    1. MySQL安装(同LAMP里面的安装方法)2.  php安装wget  http://cn2.php.net/distributions/php-5.4.37.tar.bz2tar jxf ph ...

  2. apache2.2 到 2.4后配置文件需要更改的部分

    参考: http://www.dotblogs.com.tw/maple ... e24_httpd_conf.aspx 1.  访问控制2.2 的时候Order deny,allowDeny fro ...

  3. JAVA之ArrayList集合

    /** * ArrayList集合讲解 * 集合的添加.遍历.删除 */package com.test; import java.util.*; public class test7 { /**   ...

  4. linux让软件停止自动更新

     停止自动更新 sudo echo "软件包名 hold" | sudo dpkg --set-selections 比如我想给mysql-server锁定当前版本不更新,命令是: ...

  5. hibernate学习系列-----(4)hibernate基本查询上篇:HQL基本查询

    紧接着上一篇,今天继续hibernate的学习总结,来聊一聊hibernate的基本查询方法,先说说HQL(hibernate Query Language):它是官方推荐的查询语言.在开始写代码之前 ...

  6. 微信小程序 - 关于下拉刷新

    // 拉取数据 fetchData: function() { wx.request({ url: 'http://v.juhe.cn/toutiao/index', data: { type: '' ...

  7. java8 lambda 与 stream

    参见:https://www.bilibili.com/video/av14372754/?p=2

  8. 使用 mybatis + flying-0.9.4 的电商后端

    代码地址如下:http://www.demodashi.com/demo/12779.html mybatis.flying - 阳春 (Sunny-Spring) 项目介绍请见 flying-doc ...

  9. 无法连接到服务器,用户xxx登陆失败"

    无法连接到服务器,用户xxx登陆失败" 该错误产生的原因是由于SQL Server使用了"仅 Windows"的身份验证方式, 因此用户无法使用SQL Server的登录 ...

  10. excel表格快捷键

    CTRL+A   全选     CTRL+B   加粗       CTRL+C   复制      CTRL+D   下拉(复制上一个单元格的格式和内容)    CTRL+G   定位 CTRL+F ...