其他分享
首页 > 其他分享> > Codeforces 1706 D,E

Codeforces 1706 D,E

作者:互联网

D
枚举max,让min最大

假设当前\(max=v\),于是对于\(0\leq a_{i}<v+1\)的数,\(p_{i}=1\)。

那么对于\(v+1\leq a_{i}<2(v+1)\)的数,首先\(p_{i}\geq 2\)(否则最大值就不是\(v\)了),并且我们想让最小值大,故我们取\(p_{i}=2\)。

我们可以推广:

若\((t-1)(v+1)\leq a_{i}\leq t(v+1)\),那么我们最优的方案是\(p_{i}=t\)。

故我们将数列分成若干块——\([0,v+1),[v+1,2(v+1)),[2(v+1),3(v+1)),...\),对于每一块,我们要找到\(\lfloor\frac{a_{i}}{p}\rfloor\)的最小值。由于同一区间内\(p\)相等,故这个最小值一定是区间内最小的\(a\)除以\(p\)的值。

我们用st表维护区间最小值,对于枚举的max=v,我们同时暴力枚举每个区间,由于调和级数\(\sum_{i=2}^{n} \frac{1}{i}=\log n\),这样时间复杂度为\(O(n\log n)\)。

E
若\(l,r\)内部的点对两两可达,那么意味着:

\[(l,l+1),(l,l+2),...(l,r)\\ (l+1,l+2),(l+1,l+3),...,(l+1,r)\\ ...\\ (r-1,r) \]

这些点对两两可达。

那么我们可以去掉一些无关的点对。我们发现,如果\((l,l+1),(l+1,l+2),...,(r-1,r)\)这\((r-l)\)个点对是两两可达的,那么其余的点对就一定两两可达。

故我们设\(f(i)=i和i+1最少什么时刻连通\),回答询问时只要回答\(f(l),f(l+1),...f(r-1)\)的最大值即可,这个可以用st表实现。(怎么又是st表啊)(这个求法很像后缀数组求lcp的过程)

那么原本我们有\(O(n^2)\)个不同的点对,现在只有\(O(n)\)个了,我们分别求\(f(1),f(2),...,f(n-1)\)的值。

如何快速求出呢?首先按顺序考虑边,如果当前加入的边\((u,v)\)在图上已经联通,那么就不必加上了,否则我们就加上这条边。(类似于kruskal算法流程,用并查集实现)

容易发现求出的是最小生成树,那么对于询问\((i,i+1)\),我们相当于查询树上从\(i\)到\((i+1)\)路径中最大的边权。这个可以用倍增实现。

时间复杂度为\(O(n\log n)\)。

标签:...,那么,log,1706,max,Codeforces,leq,我们
来源: https://www.cnblogs.com/Nastia/p/16503954.html