Description
你有一个长为\(n\)的正整数序列\(A\),要求滋磁如下操作(\(q\)次):
1 l r x
:对于区间\([l, r]\),询问是否可以修改其中的至多一个数,使得这段区间内数的最大公约数为\(x\)。2 i x
:将\(A_i\)修改为\(x\)。
\(1\leq n, q\leq 500000, A_i, x\leq 10^9\)。
Solution
考虑询问那个条件的本质……
首先如果区间内恰有一个数不是\(x\)的倍数,那么改掉那个数就行;如果没有一个不是\(x\)的倍数,那么随便改一个就完事了;对于其他情况,就玩不动了。因此,条件等价于区间内不是\(x\)的倍数的数至少有一个。
那么我们考虑从\(l\)开始向右,构造一个极长的为\(x\)倍数的段,再从\(r\)向左构造这么一个,那么如果区间内全是\(x\)的倍数的话这两个段就重了,只有一个不是的话那么这两个段会在一个地方断开。
然后考虑怎么去求这两个段……首先显然可以维护区间\(\gcd\),然后二分答案求出这个段长度,但是这样的话复杂度是\(O(n\log^3 n)\)的,很吃不消。因此我们把那个普通的二分,改成线段树上二分,就跑的匪快了(单次求复杂度只有\(O(\log n)\))。
Code
1 |
|