CF1843F1 Omsk Metro (simple version) 题解

发布时间 2023-11-30 00:05:15作者: ShawyYum

题意:

维护一棵树,初始有一个编号为 $ 1 $ ,点权为 $ 1 $ 的根节点,后续进行 $ n $ 次操作,操作分为两种:

  1. $ + $ $ v_i $ $ x_i $ :表示添加一个点权为 $ x_i $ $ (x_i \in $ { $ -1,1 $ } $ ) $ 的节点,并使其与点 $ v_i $ 连边,节点编号为此时点的总数。

  2. $ ? $ $ u_i $ $ v_i $ $ k_i $ :表示查询点 $ u_i $ 到点 $ v_i $ 的最短路径上是否存在一个子路径使得所经过的点的点权和为 $ k_i $ ,子路径可为空,此时点权和为 $ 0 $ 。

数据保证:维护的一定是一棵树,查询时 $ u_i $ 一定为根节点 $ 1 $ , $ v_i $ 一定为已存在的点。

思路:

考虑长度为 $ len $ 的数组 $ a $ ,最小连续子段和为 $ minv $ ,最大连续子段和为 $ maxv $ ,如果 $ a_i $ ∈ \(\{\) -1,1 \(\}\) ,那么对于任意 $ x $ ∈ $ [ $ minv,maxv $ ] $ ,数组 $ a $ 中一定存在和为 $ x $ 的连续子段。

证明:对于数组 $ a $ 中任意一个连续子段 $ [l,r] $ ,其首尾两端增删一个元素,子段和仅会 $ +1 $ 或 $ -1 $ 。而从最小连续子段和 $ minv $ 变为最大连续子段和 $ maxv $ ,只需要不断增删首尾两端的元素,所以一定存在和为 $ x $ ∈ $ [minv,maxv] $ 的连续子段。

离线处理:先建树,后查询。

由于维护的是一棵树,那么从根节点 $ 1 $ 到任意节点 $ v $ 的路径唯一。考虑树形 $ dp $ 。

先从根节点做一次 $ dfs $ :

$ minv[v][1] $ :表示从根节点 $ 1 $ 到节点 $ v $ 的路径中以 $ v $ 为结尾的最小连续子段和

$ maxv[v][1] $ :表示从根节点 $ 1 $ 到节点 $ v $ 的路径中以 $ v $为结尾的最大连续子段和

设节点 $ v $ 的父节点为 $ u $ ,那么状态转移方程有:

$ minv[v][1] $ $ = $ $ min $ $ ( $ $ val[v] $ ,$ minv[u][1] $ $ + $ $ val[v] $ $ ) $

$ maxv[v][1] $ $ = $ $ max $ $ ( $ $ val[v] $ ,$ maxv[u][1] $ $ + $ $ val[v] $ $ ) $

再从根节点做一次 $ dfs $ :

$ minv[v][0] $ :表示从根节点 $ 1 $ 到节点 $ v $ 的路径中的最小连续子段和。

$ maxv[v][0] $ :表示从根节点 $ 1 $ 到节点 $ v $ 的路径中的最大连续子段和。

设节点 $ v $ 的父节点为 $ u $ ,那么状态转移方程有:

$ minv[v][0] = min(minv[v][1],minv[u][0]) $

$ maxv[v][0] = max(maxv[v][1],maxv[u][0]) $

查询时,先特判 $ k_i $ 是否为 $ 0 $ ;如果 $ k_i $ 不为 $ 0 $ ,再判断是否满足 $ k_i ∈ [minv[v_i][0],maxv[v_i][0]] $ 即可。