結點全部兒子裏子樹規模最大的結點,即\(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; }
最後用線段樹維護區間和便可。