A. Tit for Tat
点点点
B. AGAGA XOOORRR
点点点
C. Baby Ehab Partitions Again
点点点
D. Cut
题意:
给定一组数
n
(
1
⩽
n
⩽
1
0
5
)
n\left(1\leqslant n\leqslant 10^5\right)
n(1⩽n⩽105),在给定区间内划分子串,使得每个子串的LCM(最小公共倍数)等于子串乘积。求每个询问
q
(
1
⩽
q
⩽
1
0
5
)
q\left(1\leqslant q\leqslant 10^5\right)
q(1⩽q⩽105)的最少划分子串数量。
题解:
首先想到的是离线莫队算法,但是由于在区间
(
L
,
R
)
(L,R)
(L,R)内部也会有划分,失败。
考虑在线算法。考虑将
(
L
,
R
)
(L,R)
(L,R)划分成
(
l
k
,
r
k
)
(l_k,r_k)
(lk,rk),那么贪心策略显然是可行的,因为对于局部最优解而言,减少了对后续划分的限制。由于这一前提,先对每一个起始点
l
l
l,求其最大子串长度,其对应的下一个子串的起始点为
r
r
r。可以用预处理的方式对每一个数分解质因数完成。但是这种方式同样没法处理区间
(
L
,
R
)
(L,R)
(L,R)内部的划分,一个技巧是用
l
+
1
l+1
l+1对应的下一个起始点更新
l
l
l,同样是贪心的思想。划分完之后,可以从起始点
l
l
l迭代至超过
r
r
r,迭代次数即为划分次数。在最坏情况下,即每个数相同情况下,每次询问时间复杂度为
O
(
n
)
O(n)
O(n)。这有一个经典技巧——可以考虑用二分加速。
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示起始点
i
i
i在
j
j
j次迭代后的点,这个迭代的距离肯定是大于
2
j
2^j
2j,那么就可以将时间复杂度降为
O
(
l
o
g
n
)
O(logn)
O(logn)。总时间复杂度为
O
(
q
l
o
g
n
)
O(qlogn)
O(qlogn)。