本文共 3322 字,大约阅读时间需要 11 分钟。
题意:

思路:
由于 a , b a,b a,b都比 c c c厉害,那么 a , b a,b a,b一定是某个是某个的祖先。那么就分为两种情况了:
( 1 ) (1) (1) b b b在
a a a上面,约定
d e p t h [ 1 ] = 1 depth[1]=1 depth[1]=1,此时答案显然为
m i n ( d e p t h [ a ] − 1 , k ) ∗ ( s e [ a ] − 1 ) min(depth[a]-1,k)*(se[a]-1) min(depth[a]−1,k)∗(se[a]−1)。
( 2 ) (2) (2) b b b在
a a a的下下面,这个时候就不是那么容易搞了,问题转化成我们要求
a a a这个子树中
d e p t h depth depth范围在
[ d e p t h [ a ] + 1 , d e p t h [ a ] + k ] [depth[a]+1,depth[a]+k] [depth[a]+1,depth[a]+k]内的所有点的
s e [ i ] − 1 se[i]-1 se[i]−1,先考虑暴力怎么写呢?显然我们可以暴力对这颗子树的深度建线段树,这样就变成了区间查询的问题了。而这样复杂度是肯定不行的,所以我们考虑建可持久化线段树,根据树的
d f s dfs dfs序建主席树,以节点深度为下标,那么查询就变成了
q u e r y ( r o o t [ d f n [ p ] ] , r o o t [ d f n [ p ] + s e [ p ] − 1 ] , 1 , n , d e p t h [ p ] + 1 , m i n ( d e p t h [ p ] + k , n ) ) query(root[dfn[p]],root[dfn[p]+se[p]-1],1,n,depth[p]+1,min(depth[p]+k,n)) query(root[dfn[p]],root[dfn[p]+se[p]−1],1,n,depth[p]+1,min(depth[p]+k,n)),再加上
( 1 ) (1) (1)的答案即可。
我们还可以将其转换成二维数点的问题。
通过以上分析不难发现我们要找的点就是
深度范围是
[ d e p t h [ p ] + 1 , d e p t h [ p ] + k ] [depth[p]+1,depth[p]+k] [depth[p]+1,depth[p]+k],
d f s dfs dfs序范围是
[ d f n [ p ] , d f n [ p ] + s e [ p ] − 1 ] [dfn[p],dfn[p]+se[p]-1] [dfn[p],dfn[p]+se[p]−1],那么我们以深度建立
x x x轴,以
d f s dfs dfs序建立
y y y轴,让后统计就好啦。
主席树 O ( n l o g n ) O(nlogn) O(nlogn)
//#pragma GCC optimize(2)#include #include #include #include #include
转载地址:http://xvlx.baihongyu.com/