有段时间没做难一点的思维题了
思路 #
首先不难发现对于每个数来说,它的第一次和最后一次出现的位置是最重要的,因为使用其他位置的操作都可以使用两端的位置完成而且中间的位置的 c 值可以被两端变成 1。我们将每个数i的第一次和最后一次位置记作li,ri,于是我们就可以将每个数表示成一个线段 [li,ri]。
对于一个线段的集合S,如果这些线段的并集等于线段[min(li),max(ri)],我们称S是连通的。对于所有线段我们可以将其划分为极大连通子集对于每个子集其互不影响所以最终的答案就是每个子集的答案之和。
对于每个极大子集S,我们可能找到其最小子集S′⊆S使得S′中的线段的并等于 S中线段的并,这样我们可以将尽量多的线段的端点的 c 值变成 1.对于 S′中的线段我们可以证明最多可以将 ∣S′∣−1个位置的 c 值变成 1。
代码 #