BZOJ2724 [Violet]蒲公英 分块
题目描述
经典区间众数题目
然而是权限题,所以题目链接放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]蒲公英 分块的更多相关文章
- BZOJ2724 [Violet]蒲公英(分块)
区间众数.分块,预处理任意两块间所有数的众数,和每块中所有数的出现次数的前缀和.查询时对不是整块的部分暴力,显然只有这里出现的数可能更新答案.于是可以优美地做到O(n√n). #include< ...
- [Violet]蒲公英 分块
发现写算法专题老是写不动,,,, 所以就先把我在luogu上的题解搬过来吧! 题目大意:查询区间众数,无修改,强制在线 乍一看是一道恐怖的题,仔细一看发现并没有那么难: 大致思路是这样的,首先我们要充 ...
- Luogu P4168 [Violet]蒲公英 分块
这道题算是好好写了.写了三种方法. 有一个好像是$qwq$$N\sqrt(N)$的方法,,但是恳请大佬们帮我看看为什么这么慢$qwq$(后面的第三种) 注:$pos[i]$表示$i$属于第$pos[i ...
- [BZOJ2724][Violet 6]蒲公英
[BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...
- 【BZOJ2724】蒲公英(分块)
[BZOJ2724]蒲公英(分块) 题面 洛谷 谴责权限题的行为 题解 分块什么的都不会,根本就没写过几次. 复杂度根本不会分析,吓得我赶快来练练. 这题要求的是区间众数,显然没有什么很好的主席树之类 ...
- 洛谷 P4168 [Violet]蒲公英 解题报告
P4168 [Violet]蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多 ...
- 【BZOJ2724】[Violet 6]蒲公英 分块+二分
[BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ...
- BZOJ2724 [Violet 6]蒲公英 分块
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ...
- 【分块】bzoj2724 [Violet 6]蒲公英
分块,离散化,预处理出: ①前i块中x出现的次数(差分): ②第i块到第j块中的众数是谁,出现了多少次. 询问的时候,对于整块的部分直接获得答案:对于零散的部分,暴力统计每个数出现的次数,加上差分的结 ...
随机推荐
- ViewPager的OnPageChangeListener三个回调解析
一个native crash最后是重写ViewPager解决的,过程中发现这三个回调还有点绕,于是理了一下 ViewPager有两个操作,一个是用手指滑动翻页,一个是直接setCurrentItem( ...
- 优化dedecms设置文章url自定义规则
DEDECMS自定义URL规则的做得还是不错的,可清楚的看到URL中可用到的变量,并且这些变量包括年月日.时间戳.文章 ID.拼音+文章ID.拼音部首.栏目目录及日期加ID转换的字符串等,基本可以很好 ...
- WordPress跳过语言包加载提高效率
WordPress 加载语言包是需要花费 0.1-0.5 秒不等的时间,所以如果 WordPress 前台可以不加载语言包,而主题中的一些文本直接写成中文,就可以加快网站的速度,并且又能保证后台的中文 ...
- 高性能MySQL中的三星索引
高性能MySQL中的三星索引 我对此提出了深深的疑问: 一星:相关的记录指的是什么??(相关这个词很深奥,“相关部门”是什么部门) 二星:如果建立了B-Tree(B+Tree)索引,数据就有序了.三星 ...
- [dt]世纪历史长河年代表
年代口诀 夏商与西周, 东周分两段, 春秋和战国, 一统秦两汉, 三分魏蜀吴, 二晋前后延, 南北朝并列, 隋唐五代传, 宋元明清后, 皇朝至此完. 中国历史长河年代表 参考: 中国历史朝代顺序表.年 ...
- 安卓手机上微信无法打开Https网址的完美解决方案
1,第三方网站检测网站的SSL证书是否正确的安装 https://www.geocerts.com/ssl-checker,大概率你会看到下边的场景,一个证书链完整的警告,如果想知道我的基础配置是什么 ...
- AWS邮件通知服务:实时监控邮件状态
以下为译文: 订阅“AWS中文技术社区”微信公众号,实时掌握AWS技术及产品消息! AWS中文技术社区为广大开发者提供了一个Amazon Web Service技术交流平台,推送AWS最新资讯.技术视 ...
- 深度学习Momentum(动量方法)
转自:http://blog.csdn.net/bvl10101111/article/details/72615621 先上结论: 1.动量方法主要是为了解决Hessian矩阵病态条件问题(直观上讲 ...
- unittest之suite测试集(测试套件)
suite 这个表示测试集,不要放在class内,否则会提示"没有这样的测试方法在类里面 ",我觉得它唯一的好处就是调试的时候可以单独调试某个class而已,我一般不用它,调试时可 ...
- BCB TLable控件透明背景属性
当我们希望一个Label适应它父窗口的背景时,设置Tranparent属性值就OK Transparent:true 透明 false 不透明