题意简述
给定一个长度为 $n\le 10^5$ 的序列,初始值$\le 10^9$,支持:1 l r x
区间 $[l,r]$ 每个数加上 $x$ 。 $|x|<=10^4,1\le l\le r\le n$2 l r x
区间 $[l,r]$ 每个数除以 $x$ (下取整),$2\le x\le 1e9,1\le l\le r\le n$3 l r
求 $[l,r]$ 中的最小值4 l r
求 $[l,r]$ 的和
询问数 $\le 10^5$
思路
显然线段树。
我们把区间除法分解成区间内每个数都减去某个数。设 $d(a,x)$ 表示 $a$ 除以 $x$ 下取整的变化量,也就是 $a-a/x$。那么 $a\leftarrow a/x$ 的操作,就等价于 $a\leftarrow a-d(a,x)$。显然,当 $x$ 相同的时候, $d$ 函数单调不减。具体的说,如果 $a<b$,则 $d(a,x)\le d(b,x)$ ,对于所有正整数 $x$。
那么对于一段区间,如果 $d(Max,x)=d(Min,x)$,那么这个区间中,所有数的变化量都一样了,直接上区间减法来解决。
否则我们继续把这个区间分成左右两个部分,直到这个区间满足上述条件即可。
分析复杂度
那么这个算法的复杂度是多少呢?看起来每次的最坏情况是暴力的 $O(r-l+1)$ ,但是我们注意到,加法操作中的 $x$ 最大才加 $10000$,但是一次除法操作每次至少除以 $2$。
那比如我是毒瘤出题人,我要卡我的代码,那肯定是要尽量多的加法操作(因为会减慢除法操作),但是也不能少了除法操作(因为看起来很慢)。那假设数据里有 $5\times 10^4$ 个加法操作,还有 $5\times 10^4$ 个除法操作。然后每个数一开始都是 $10^9$ 的规模(不一定恰好是 $10^9$ ,全部相同反而会加快除法操作)。
那加完之后每个数都是 $1.5\times 10^9$ 左右。那么我们把它除个 $31$ 次就全部变成 $0$ 了,那肯定变化量相同,就是能用 $O(log)$ 的减法操作实现了。
那总共就相当于 $O(n \log n \log a)$ ,其中 $a$ 是初始的值域,$\log a$ 大约要到 $32$ 了。
代码 (今天测试一下展开功能)
1 |
|