$ [ZJOI2019] $语言

Posted ljc20020730

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$ [ZJOI2019] $语言相关的知识,希望对你有一定的参考价值。

~~ 话说,本题考场想出三只\(log\)的暴力做法,被卡成暴力了。~~

题目分析

首先考虑枚举每一个点,计算这个点可以和多少点进行交易。

将所有经过该点的路径\(s,t\)拿出,那么这些极远的\(s,t\)构成的连通块大小\(sz - 1\)就是答案。

\(Codeforces\)\(异象石\)那题可以想到,若一些点集按照\(dfs\)序排序,那么这些点构成连通块大小就是

\(\frac12 (dist(a_1 , a_2) + dist(a_2,a_3) + ... + dist(a_k-1 , a_k) + dist(a_k,a_1))\)

考虑对于每一个节点开一棵线段树,其叶子节点\(i\)表示\(dfs\)序为\(i\)的极远点出现次数。

线段树中存储\(3\)个值\(lp,rp,Sum\)分别表示当前存在的大于\(0\)的最小下标和最大下标,和不算头尾的连通块大小。

由于路径条数为\(m\),显然我们可以用可持久化线段树来维护这\(n\)棵线段树,使得空间复杂度为\(O(m log_2 n)\)

利用树上差分的思想,对于每一条\(s,t\)的路径,我们先在\(s\)\(t\)所在的线段树中将\(dfn[s]\)\(dfn[t]\)两个点单点\(+1\)

然后在\(father(lca(s,t))\)的节点,将\(dfn[s]\)\(dfn[t]\)两个点单点\(-2\)

于是,我们可以自下往上去统计每个节点的答案。

每一次,我们需要对该节点的所有子树进行线段树合并,然后询问这个节点的答案,将其累加进总个数中。

这样,我们就完成了无序数对的统计,那么此时答案除以\(2\)就是最终的答案。

复杂度分析

由于\(n\)次线段树合并节点总数是\(m\)个,所以需要时间复杂度为\(O(m log_2 n)\)

由于\(m\)次线段单点修改,使用\(O(1)\)\(LCA\)实现,所以需要时间复杂度为\(O(m log_2 n)\)

所以,本题的总时间复杂度就是\(O(m log_2 n)\)

以上是关于$ [ZJOI2019] $语言的主要内容,如果未能解决你的问题,请参考以下文章

P5327 [ZJOI2019]语言

题解Luogu P5327 [ZJOI2019]语言

[ZJOI2019]线段树

「ZJOI2019」线段树

bzoj 1058 [ZJOI2007]报表统计(set)

2019.03.13 ZJOI2019模拟赛 解题报告