第三期ccb
CF519E 2100
虽然是一道2100的题,但还是比较好想的。在树上找到最短距离,明显需要用到公共祖先之类的算法,并且,还要明确的知道节点往上走几步会到哪个节点。因此,学习了dfn序求LCA的方法。
具体来说在dfs序中,两个节点之间的dfn一定会遍历到lca的儿子节点,而这个儿儿子节点距离根比较近,同时是这个区间内父亲节点dfn序最小的。于是在dfn序中构建一个st表,用来记录这个区间中dfn序最小的节点是哪个。st[0][dfn[u] = ++ dn] = f;
可以看到保存的是父亲节点
所以,st表保存了dfn序更小的父亲节点是哪个,最小的那个父亲节点就是lca。
学完lca之后,用这个找到lca,然后看其中一个节点是否是lca,分类讨论一下。最后需要,再用倍增的方法找到子树对应的节点,然后用子树的节点数算一下中间点有多少个。这道题我写的不是很熟练,好想但不好写,可能是图论的题写的比较少的原因。
CF1637E 2100
这道题完全没有想出来。说是一个时间复杂度的trick也好,或者说是理解了根号分治之后自然而然产生的想法也好。总之,这道题用到了两个东西\(cnt_x\)与\(x\),入手点是\(\sum cnt=n\),因此\(cnt\)的种类有\(\sqrt n\)种,于是枚举每个\(x\)的时间复杂度是\(O(n)\),枚举每种\(cnt_y \leq cnt_x\)的时间复杂度是\(O(log(n))\),在\(x = y\)时和\(\{x, y\}\)不合法的时候转到更小的(m次),否则用\(cnt_y\)里最大的\(y\)就行了。
最后的时间复杂度时\(O(nlog(n) + m)\)。
CF2052J 2000
这道题没写,改天吧。
第四期ccb
CF883H 1800
一道构造题,把所有因数拆出来,分类讨论一下。
CF1660F1 1700
构造,需要找到左右离得最近的加号,然后遍历所有区间,用前缀和之类的方法优化之类的。
CF1184E1 1900
这道kruskal可真kruskal啊,看到最小生成数之类的会想到,然后想一下就行了。
CF1260D 1900
刚开始以为和上一道一样是一道唐题,然后惨败于此题,看了错误样例之后发现,还需要区间合并,才是正确的答案,结果又WA了,后来才修改了区间合并的右端点操作的失误,才过了。确认完毕,是一道挺好的二分题。