題目鏈結
一道很有意思的題。
我們考慮按位累計貢獻。記錄\(dp[i][j]\)為上一步倍增跳了\(2^j\)步,跳到了\(i\)點的所有狀態"1"的個數和。
可以理解為,對於乙個兒子u
和他的祖先v
的深度差,可以表示為乙個二進位制數。我們倍增的將u
跳到v
,每次跳的長度一定比上次小,且一定是\(2^k\)。
對於乙個點i
,上一步跳了\(2^j\)步,那麼就\(\forall k,k,dp[fa][k]+=dp[i][j]+num[i][j]
。其中fa
代表的是i
第\(2^k\)個祖先,num
代表的是某個狀態有多少種方案。那麼這句話的意思就是,對於所有可以由\((i,j)\)這個狀態轉移到的狀態,都把他們的dp
加上\((原狀態dp值+原狀態方案數那麼多個「1」)\)。同時num[fa][k]+=num[i][k]
,ans+=dp[fa][k]*(size[fa]-size[from]-1)
,from
指的是這一次是從fa
的哪個親兒子跳上來的。
那麼連初始化都不需要了,直接多考慮一種情況跳躍即可。
51nod 1709 複雜度分析
考慮樸素的暴力,相當於列舉u點的每個祖先f,然後統計一下這個點f除了某個兒子裡有u的那個子樹之外的節點個數,乘上f到u距離的二進位制1的個數 那麼我們用倍增來實現這個東西,每次列舉二進位制的最高位j,用dfs序列舉點u,找到u的距離為 2 j 的祖先,那麼在fa u j 這個祖先的位置,j這一位的出...
樹論 倍增 51nod1709 複雜度分析
倍增與位運算有很多共性 這題做法有一點像 線段樹上二分 和 線段樹套二分 的關係。給出一棵n個點的樹 以1號點為根 定義dep i 為點i到根路徑上點的個數。眾所周知,樹上最近公共祖先問題可以用倍增演算法解決。現在我們需要算出這個演算法精確的複雜度。我們定義計算點i和點j最近公共組先的精確複雜度為b...
複雜度分析 時間複雜度分析和空間複雜度分析
其實,只要講到資料結構與演算法,就一定離不開時間 空間複雜度分析。而且我個人認為,複雜度分析是整個演算法學習的精髓,只要掌握了它,資料結構和演算法的內容基本上就掌握了一半。1.時間複雜度分析 對於剛才羅列的複雜度量級,我們可以粗略地分為兩類,多項式量級和非多項式量級。其中,非多項式量級只有兩個 o ...