题目描述

经典区间众数题目

然而是权限题,所以题目链接放Luogu的

题解

因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法

就是那种要用二分的,并不会clj那种不带log的做法

首先数的值域为1e9肯定要离散化一下

因为数最多有40000个所以开40000个vector,存一下每个数出现的位置

预处理出每个以块的端点为左右端点的区间的众数,这种区间一共有O(block^2)个,所以可以用O(n*block)的时间复杂度来预处理

可以发现的一点是,每个区间的众数,要么是散块里面的数,要么是中间所有整块的区间众数(因为散块中出现的那些数增加了中间的整块中第二大第三大的这些区间众数的出现次数,他们就有可能篡位了)

那么我们可以在离散化之后,将每个数出现的位置存到一个vector里面,在处理散块中的数的时候,我们可以通过二分查找找出这个区间中该数出现过几次(二分查找右端点和左端点相减),效率是$O(\sqrt{n}*log(n))$

整块直接调用我们预处理出来的区间众数就可以了

#include <bits/stdc++.h>

#define ll long long
#define inf 0x3f3f3f3f
#define il inline namespace io { #define in(a) a=read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n') #define I_int int
inline ll read() {
ll x = , f = ; char c = getchar() ;
while( c < '' || c > '' ) { if( c == '-' ) f = - ; c = getchar() ; }
while( c >= '' && c <= '' ) { x = x * + c - '' ; c = getchar() ; }
return x * f ;
}
char F[ ] ;
inline void write( I_int x ) {
if( x == ) { putchar( '' ) ; return ; }
I_int tmp = x > ? x : -x ;
if( x < ) putchar( '-' ) ;
int cnt = ;
while( tmp > ) {
F[ cnt ++ ] = tmp % + '' ;
tmp /= ;
}
while( cnt > ) putchar( F[ -- cnt ] ) ;
}
#undef I_int }
using namespace io ; using namespace std ; #define N 100010 map< int , int > mp ;
vector< int > vt[ N ] ;
int val[ N ] , a[ N ] ;
int t[ ][ ] ;
int n , tot = ;
int block , num , bl[ N ] , L[ N ] , R[ N ] ;
int cnt[ N ] ; void pre( int x ) {
int mx = , id = ;
memset( cnt , , sizeof( cnt ) ) ;
for( int i = L[ x ] ; i <= n ; i ++ ) {
cnt[ a[ i ] ] ++ ;
if( cnt[ a[ i ] ] > mx || (cnt[ a[ i ] ] == mx && val[ a[ i ] ] < val[ id ] ) ) {
mx = cnt[ a[ i ] ] ; id = a[ i ] ;
}
t[ x ][ bl[ i ] ] = id ;
}
} void build() {
block = ;
num = n / block ;
if( n % block ) num ++ ;
for( int i = ; i <= num ; i ++ ) {
L[ i ] = (i - ) * block + ;
R[ i ] = i * block ;
}
R[ num ] = n ;
for( int i = ; i <= n ; i ++ ) bl[ i ] = (i - ) / block + ;
for( int i = ; i <= num ; i ++ ) pre( i ) ;
} int serach_ans( int l , int r , int x ) {
return upper_bound( vt[ x ].begin() , vt[ x ].end() , r ) - lower_bound( vt[ x ].begin() , vt[ x ].end() , l ) ;
} int query( int l , int r ) {
int mx = , id = t[ bl[ l ] + ][ bl[ r ] - ] ;
mx = serach_ans( l , r , id ) ;
if( bl[ l ] == bl[ r ] ) {
for( int i = l ; i <= r ; i ++ ) {
int x = serach_ans( l , r , a[ i ] ) ;
if( x > mx || (x == mx && val[ a[ i ] ] < val[ id ])) { mx = x ; id = a[ i ] ; }
}
return id ;
}
for( int i = l ; i <= R[ bl[ l ] ] ; i ++ ) {
int x = serach_ans( l , r , a[ i ] ) ;
if( x > mx || (x == mx && val[ a[ i ] ] < val[ id ])) { mx = x ; id = a[ i ] ; }
}
for( int i = L[ bl[ r ] ] ; i <= r ; i ++ ) {
int x = serach_ans( l , r , a[ i ] ) ;
if( x > mx || (x == mx && val[ a[ i ] ] < val[ id ])) { mx = x ; id = a[ i ] ; }
}
return id ;
} int main() {
n = read() ; int m = read() ;
int ans = ;
for( int i = ; i <= n ; i ++ ) {
a[ i ] = read() ;
if( mp[ a[ i ] ] == ) { mp[ a[ i ] ] = ++ tot , val[ tot ] = a[ i ] ; }
a[ i ] = mp[ a[ i ] ] ;
vt[ a[ i ] ].push_back( i ) ;
}
build() ;
for( int i = ; i <= m ; i ++ ) {
int l = read() , r = read() ;
l = (l + ans - ) % n + , r = (r + ans - ) % n + ;
if( l > r ) swap( l , r ) ;
outn( ans = val[ query( l , r ) ] ) ;
}
return ;
}

BZOJ2724 [Violet]蒲公英 分块的更多相关文章

  1. BZOJ2724 [Violet]蒲公英(分块)

    区间众数.分块,预处理任意两块间所有数的众数,和每块中所有数的出现次数的前缀和.查询时对不是整块的部分暴力,显然只有这里出现的数可能更新答案.于是可以优美地做到O(n√n). #include< ...

  2. [Violet]蒲公英 分块

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

  3. Luogu P4168 [Violet]蒲公英 分块

    这道题算是好好写了.写了三种方法. 有一个好像是$qwq$$N\sqrt(N)$的方法,,但是恳请大佬们帮我看看为什么这么慢$qwq$(后面的第三种) 注:$pos[i]$表示$i$属于第$pos[i ...

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

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

  5. 【BZOJ2724】蒲公英(分块)

    [BZOJ2724]蒲公英(分块) 题面 洛谷 谴责权限题的行为 题解 分块什么的都不会,根本就没写过几次. 复杂度根本不会分析,吓得我赶快来练练. 这题要求的是区间众数,显然没有什么很好的主席树之类 ...

  6. 洛谷 P4168 [Violet]蒲公英 解题报告

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

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

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

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

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

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

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

随机推荐

  1. 【Jmeter】如何通过文件导入方式对用户名和密码进行参数化设置

    JMeter 参数化 注意:param和data body只能用一个.所有任何一个里面有内容,切换都会报错,这不是问题,jmeter是这么设计的 方法一:通过添加CSV Data Set Config ...

  2. dedecms后台每页文章条数如何修改(“文档列表”每一页显示的文档条数)

    小明在学习采集,弄了个dedecms作为发布平台,几个小时后跑来报喜说好简单,但又不想制造那么多spam,每个分类只保留几条就好.在后台删除这些文章,每页只显示30个,看了下有100多页,立马沮丧了, ...

  3. win8 metro 自己写摄像头拍照项目

    这个项目不是用的系统自带的CameraCaptureUI.是自己写的摄像头的调用,界面做的不好所以,不放了.可是能够实现拍照功能: 以下是using 程序命名空间: using Windows.Med ...

  4. HTML5 脚本 语言代码 URL 符号实体 ASCII码 颜色

    1.HTML<noscript> 标签 <noscript> 标签提供无法使用脚本时的替代内容,比方在浏览器禁用脚本时,或浏览器不支持客户端脚本时. <noscript& ...

  5. lua的文件管理

    lua没有自己的文件管理 只有读取和写入文件,但是可以通过调用lfs(LuaFileSystem),lfs是一个 用于lua进行文件访问的库,支持lua5.1和lua5.2,并且跨平台 lfs的使用: ...

  6. Fisher精确检验【转载】

    转自:https://en.wikipedia.org/wiki/Fisher%27s_exact_test https://www.cnblogs.com/Dzhouqi/p/3440575.htm ...

  7. git 下载单个文件 已经添加多个远程服务器

    175down vote It is possible to do (in the deployed repository) git fetch followed by git checkout or ...

  8. qt mysql驱动问题解绝

    传统解决方法:一.解决问题 本文解决在Ubuntu16.04系统下,Qt5无法连接MySQL数据库的问题(Qt5缺少MySQL驱动,Qt5缺少libqsqlmysql.so动态库,如何安装libqsq ...

  9. Java中如何优雅地删除List中的元素

    在工作中的许多场景下,我们都会使用到List这个数据结构,那么同样的有很多场景下需要删除List中的某一个元素或某几个元素,那么我们该如何正确无误地删除List中的元素的,今天我来教大家三种方式. 前 ...

  10. keras中TimeDistributed

    TimeDistributed这个层还是比较难理解的.事实上通过这个层我们可以实现从二维像三维的过渡,甚至通过这个层的包装,我们可以实现图像分类视频分类的转化. 考虑一批32个样本,其中每个样本是一个 ...