考虑一个玩家的路径 $(x,y)$ 对路径上的一个节点 $u$ 的贡献
设 $lca=LCA(x,y)$ ,当 $u$ 在链 $x,lca$ 上时,路径会产生 $1$ 的贡献当且仅当 $dep[x]-dep[u]=w[u]$
其中 $dep[i]$ 表示节点 $i$ 的深度,$w[i]$ 就是题目给出的 $W$,上式即 $dep[x]=dep[u]+w[u]$
当 $u$ 在链 $lca,y$ 上时,路径会产生贡献当且仅当 $dep[y]-dep[u]=dis(x,y)-w[u]$
其中 $dis(x,y)$ 表示节点 $x,y$ 的路径长度,上式即 $dep[y]-dep[u]=dep[x]+dep[y]-2dep[lca]-w[u]$
即 $-dep[x]+2dep[lca]=dep[u]-w[u]$
直接树链剖分并对每种深度维护动态开点线段树,分别维护上面两种情况,对于一条路径 $(x,y)$ 直接把对应深度的线段树的, $x$ 到 $y$ 的所有节点$+1$
即深度为 $dep[x]$ 和深度为 $-dep[x]+2dep[lca]$ ,注意这是两种情况,对每种深度都要两颗线段树分别维护
因为有第二种情况的深度可能有负数,所以要把深度加 $N$ 转成正的,变成 $2dep[lca]-dep[x]+N$,并注意这样搞 $lca$ 会被算两次,要减一次
查询节点 $u$ 时就查询深度为 $dep[u]+w[u]$ 和 $dep[u]-w[u]+N$ (注意$+N$)的线段树上节点 $u$ 的值就好了
线段树的最大节点数要注意算好,代码中线段树用标记永久化,又好写速度又快
#include #include #include #include #include #include