结点全部儿子里子树规模最大的结点,即\(sz[ x ]\) 最大。算法
我第一次接触这个概念竟然不是在这,而是在这。spa
有时间再写题解吧,这是一个不错的思惟题。get
从重儿子一直延伸到叶子结点的路径。class
任意两点间的距离 ( 不严谨的说。原理
先跑重儿子,回来再跑轻儿子,最后造成一个特殊的 dfs 序。top
\(1.\) 处理出须要的信息:时间
\(de , fa , sz , top\)(所处于重链的起点编号)。query
\(2.\) 跑特殊的 \(dfs\) ,造成 \(dfs\) 序。while
一条链上的序是连续的。
一棵子树内的 dfs 序为 \(dfn[x]\) 到 \(dfn[x] + sz[x] + 1\),也是连续的。
给一棵子树或者一条树链上的结点所有加上一个权值。
利用特殊 dfs 序的性质,分几步来看:
假设如今要将树链 \((x , y)\)上的权值加上某个数。
\(1.\) 若是 \(x\) 和 \(y\) 所处链不一样,选取深度较大的结点爬到链端处,一边跑一边把路径上的结点加上权值 (感性理解)。
\(2.\) 最后确定有一个结点跑到 \(x\) 和 \(y\) 的 \(lca\) 处。
\(3.\) 处理 \(LCA\) 到另一个结点的那段就可。
inline int qRange(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); res=0; query(1,1,n,id[top[x]],id[x]); ans+=res; ans%=mod; x=fa[top[x]]; } if(dep[x]>dep[y])swap(x,y); res=0; query(1,1,n,id[x],id[y]); ans+=res; return ans%mod; }
最后用线段树维护区间和便可。