1. 程式人生 > >BZOJ 世界樹

BZOJ 世界樹

第一步首先建虛樹

第二步兩遍dfs,一次從葉子到根,一次從根到葉子,就可以得到虛樹中每個節點在M個詢問點中離他最近的是哪個(簡稱為控制點)

第三步考慮計算答案,對於整個樹,我們把節點化為三個種類

  1.節點在虛樹的葉子節點的子樹中

  2.節點在虛樹根節點之上的部分

  3.節點在虛樹兩個節點之間

對於第一和第二種節點,我們很好統計答案的貢獻分別為當前節點子樹的大小和總節點的個數減去當前節點子樹大小

而對於第三種,假設虛樹上每對相鄰節點深度小的為U,深度大的為V.

  如果U的控制點和V的控制點相同,那麼顯然U與V之間的部分只對一個答案有貢獻,該答案即為U與V的控制點.

  如果U的控制點與V的控制點不同,假設U的控制點為I,V的控制點為J.那麼他們肯定是I->U->V->J這樣的深度遞增序

如果dis(U,V)+dis(V,J)>(dis(I,U)+dis(U,V)+dis(V,J))/2>dis(V,J) 那麼U與V之間的部分就會被分為兩個部分

利用倍增從V開始跳(dis(I,U)+dis(U,V)-dis(V,J))/2找到分界點分別統計貢獻.