这里是被楼上Froggy大佬点名爆踩的做法qaq。
废话有点多,不想看直接跳
在太阳西斜的这个世界里,置身天上之森。 等这场战争结束之后,不归之人与望眼欲穿的众人,人人本着正义之名。 长存不灭的过去;逐渐消逝的未来。 我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘。
————世界上最幸福的女孩 珂朵莉
不愧是Ynoi,如此毒瘤。
这是我Ynoi一血初始化那题暴力艹过去的qaq。
想了一个小时,深感此题毒瘤
$\texttt{Description}$
给你一个序列,每次操作可以增加一个数,也可以查询对于一个数 $x$,将这个序列从小到大排序后找到最小的 $i$ 满足 $\lceil \frac{a_{i+1}}{x}\rceil -1> \lceil \frac{a_i}{x}\rceil$(若当前序列长度为 $n$,令 $a_{n+1}=\infty$)
$\texttt{Solution}$
题目说了 $h\le n\le 10^5$,因此我们盲猜这题要用权值线段树or权值树状数组。再看到每次查询一段区间的期望值,还要乘上这段区间的长度,其实就是求每种方案的总和,查询区间 $[l,r]$ 对应的答案的总和……再一看数据范围,显然要用一个支持修改和区间查询的数据结构维护答案。
$n\le 10^5,m\le 10^6$,Ynoi不用分块惹爷青结
至于如何维护答案,我们将每个随从的血量放到一个权值树状数组里面,每次增加一个随从,找到被他影响的答案,然后暴力调整即可。
为什么说是暴力调整呢?
形象的理解一下,上面向上取整可以理解为对这个权值树状数组进行分块。数组的每个值 $d_i$ 表示血量为 $d_i$ 的随从的数目。块长为 $x$,我们要求的就是最早哪个块里面的数字均为 $0$。
由于 $x$ 的取值在 $[1,n]$ 之间,所以每次暴力往后跳最多也就不跳超过 $\sum\limits^{i\le n}_{i=1}\frac{n}{i}\approx nlogn$。
每次跳的时候查询一下树状数组,当前这个块是否全部为 $0$,如果不是就往后跳。
现在的问题是不可能每加进来一个随从就把所有块往后跳,因为就算总共跳的次数少,把这些块遍历一遍也需要 $O(n)$ 的时间。因此我们需要找到对于当前血量为 $h$ 的随从,有多少块经过了 $h$ 这个点。将这些块全部删除并往后跳,再把新的块插入进去。
现在需要一种数据结构,支持三种操作:
- 插入一条线段
- 删除一条线段
- 查询经过了给定点的所有线段
对于给定点 $h$,经过它的线段左端点必然在 $[1,h]$ 之间,不妨把每条线段的左端点看做下标,则我们每次查询左端点在 $[1,h]$ 之间的线段右端点最大的,将它往后调整后删除,直到当前查询到的最大右端点 $<h$ 为止。就是一个动态的RMQ,我使用线段树维护。(当然可能有多个线段左端点一样,因此线段树每个叶子节点对应一个大根堆而不是一个数)。
然后维护一个表示答案的树状数组,每次暴力往后跳块后就要更新它。
貌似很多神仙用set
被卡常了,显然用set
常数比堆大得多啊……
$\texttt{Code}$
由于没有刻意卡常,所以是我的正常马蜂。
1 |
|