11.28模拟赛D题解

一个奇妙的不等式操作:
\(a_x+a_y\geq (a_x xor a_y)=f_x-f_y\)
所以只有\(a_x+a_y\geq f_x-f_y\)的点才能贡献答案。
这个东西的意义是\(a_x\geq 在\)x\(子树且不包含\)x\(,\)y\(子树的点\)
考场上猜了符合这个条件的点对只有\(n\log_2\max a_i\),结果真的猜对了。
要证明这个需要证明两个引理:
1.合法的候选\(y\)集可能在多个子树中,但是一定在一个子树的链中。
假设有两个点\(x,y\)不在一条直上/下的链上,则设他们的lca是\(lc\)
显然\(a_x\geq a_y+a_{lc}\)\(a_y\geq a_x+a_{lc}\)
\(a_{lc}\)一定大于\(0\)所以矛盾。
2.一个子树候选点最多只有\(\log_2{\max a_i}\)个。
构造一数列\(b_x\)表示\(x\)\(x\)必须是候选集内节点)到父亲的链的\(a\)的和。
显然\(a_x\geq b_{ff_x} ,b_{x}=b_{ff_x}+a_x\)\(ff_x\)表示它的祖先中,深度最大的候选点。
显然\(b_x\)每次至少会比\(b_{ff_x}\)翻倍,证完。
所以符合这个条件的点对在最坏情况下只有\(\sum deg_i*\log_2{\max a_i}=n\log_2{\max a_i}\)
所以可以轻松的计算答案。
算法1:显然使用dfs序+线段树即可轻松的维护一个点往外的权值,然后在线段树上dfs统计答案,当区间最小值\(>0\)的时候break,但是没调出来。
算法2:注意到一个点在dfs的计算过程中(逆dfs遍历所有点),成为候选集的位置,肯定是一段连续的区间。
在考虑到它的点(祖先)肯定越高越不可能满足要求。
所以可以把当前点的候选集合并到祖先然后暴力计算。
实际上,在考场上我想到了算法2,但是以为时间复杂度是错的没写。

posted @ 2020-11-29 12:28  celerity1  阅读(75)  评论(0)    收藏  举报