题目描述

经典区间众数题目

然而是权限题,所以题目链接放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. extjs分页

    1.本地分页:设置store的proxy属性为pagingmemoryproxy实例 2.远程分页

  2. http如何301到https呢?

    HTTPS协议的站点信息更加安全,同时可降低网站被劫持的风险,Firefox和chrome浏览器对访问一些非https站点会提示风险,BD等搜索引擎也明确表态了对https站点的友好.那么我们如何部署 ...

  3. Agreementhasbeenupdated--EditPhoneNumber

    1.https://appleid.apple.com/#!&page=signin 登录appid账号  在账户里面的编辑 添加更多信息,新增手机号 2.如果不可以 可以试下这个https: ...

  4. linuxbash 父进程 子进程

    linux登陆linux,就获得一个bash,之后你的bash就是一个独立的进程,被称为pid的就是,之后你在bash下面执行的任何命令都是由这个bash所衍生的,那些被执行的命令被称为子进程.子进程 ...

  5. VCS中的覆盖率分析

    VCS在仿真过程中,也可以收集Coverage Metric.其中覆盖率类型有: 1)Code Coverage:包括control_flow和value两部分的coverage,line_cover ...

  6. <<Joint Deep Modeling of Users and Items Using Reviews for Recommendation>> 评论打分预测

    综述: 本文将 CNN 与 FM(Factorization Machine) 结合,基于评论文本来进行评分预测. 简介: 目前将神经网络应用推荐系统的研究工作中,有一类思路是把如CNN等神经网络作为 ...

  7. 人生苦短之我用Python篇(socket编程)

    socket模块 实现简单的远程连接: 客户端: import socket client = socket.socket()#声明socket类型,同时生成socke连接t对象 client.con ...

  8. 174. Dungeon Game(动态规划)

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  9. yii2常用的migrate命令

    开发中经常会用到的方法小结: 1../yii migrate xxx_xx 在表中插入某字段 : public function up() {$this->addColumn('{{applic ...

  10. zw版【转发·台湾nvp系列Delphi例程】HALCON SigmaImage1

    zw版[转发·台湾nvp系列Delphi例程]HALCON SigmaImage1 procedure TForm1.Button1Click(Sender: TObject);var img, im ...