摘要:
本文清北學堂noip訓練營試題t3試題。
樣例讀入:
4
1 21 3
2 4樣例輸出:
8樣例解釋:
}解析:
樹形dp+倍增
回想倍增法求lca的過程
從大到小列舉k,每次跳2^k步,只要不越界就跳,最後一定能跳到lca
因為跳的都是2的冪次步,所以每跳一步就是二進位制加了乙個1
先預處理fa[i][k],表示點i向上跳2^k 步的祖先節點
設 f[i][j] 表示最後一步跳了2^j步,跳到了點i的答案之和
cnt[i][j] 表示最後一步跳了2^j步,跳到了點i的方案數
因為有了倍增求lca原理的保證,所以只需要考慮跳2的冪次步
設siz[i]表示以i為根的子樹的大小
rt[i]=j 表示 當前點屬於 i的子樹裡,以j為根節點的子樹
假設dfs回溯到x,轉移分兩種:
1、以x為鏈的乙個端點
列舉x向上跳2^k次,則v=fa[x][j]
那麼ans+=siz[v]-siz[rt[v]] ——所有非rt[v]子樹的點,與x的lca都是v,都會有1的貢獻
(類似於點分治中要去除同一子樹內合法的點)
cnt[v][k]++ f[v][k]++
2、x作為倍增過程中的乙個中途點
那麼列舉最後一步跳了2^i 跳到了x
列舉x再往上跳2^j步,則v=fa[x][j]
那麼ans+=(f[x][i]+cnt[x][i])*(siz[v]-siz[rt[v]])
f[x][i] 是原來的答案,在以v做lca時,又會用 (siz[v]-siz[rt[v]])次
cnt[x][i] 是 要再往上跳2^j步,又有乙個1的貢獻
cnt[v][j]+=cnt[x][i] f[v][j]+=f[x][i]+cnt[x][i]
例:1–2--3–4 如果4到1的距離為3,二進位制為11,對答案的貢獻為2
回溯到4的時候,以4為端點會累積3–4 2–4
回溯到3的時候,以3為端點會累積2–3 1–3
回溯到2的時候,以2為端點會累積1–2,以2為中途點會累積1–2--3–4
(4跳21累積到2裡,然後在列舉2為中途點時,最後一步跳了21到2,2再往上跳2^0)
為什麼在列舉3作為中途點的時候,不列舉跳了2^0次方到了3
因為此時3不是中途點,我們是按跳2^k,k是降序跳的
NOIP訓練營內部試題 分糖果
noip訓練營內部試題 分糖果 摘自 清北學堂noip訓練營試題t2 題目 分糖果 分糖果 candy time limit 1000ms memory limit 128mb 題目描述 總共有n顆糖果,有3個小朋友分別叫做l,y,k。每個小朋友想拿到至少k顆糖果,但這三個小朋友有乙個共同的特點 對...
訓練營第四天 二叉樹
一 基礎知識 二叉樹 二叉樹是乙個連通的無環圖,並且每乙個頂點的度不大於3。有根二叉樹還要滿足根結點的度不大於2。有了根結點之後,每個頂點定義了唯一的父結點,和最多2個子結點。然而,沒有足夠的資訊來區分左結點和右結點。如果不考慮連通性,允許圖中有多個連通分量,這樣的結構叫做森林 遍歷 遍歷是對樹的一...
鄧俊輝 演算法訓練營練習 二叉排序樹
先序遍歷 輸出自己 左子樹 右子樹 中序遍歷 輸出左子樹 自己 右子樹 include using namespace std struct node t 10000 root代表根節點 cnt代表二叉樹大小 int root,cnt 建樹 int insert int v,int x t x lc...