牛客演算法周周練2 小H和遊戲(樹 思維)

2021-10-05 04:31:21 字數 1299 閱讀 9275

小h正在玩乙個戰略類遊戲,她可以操縱己方的飛機對敵國的n座城市(編號為1~n)進行轟炸

敵國的城市形成了一棵樹,小h會依次進行q次轟炸,每次會選擇乙個城市a進行轟炸,和這座城市距離不超過2的城市都會受損(這裡距離的定義是兩點最短路徑上的邊數),轟炸結束後,小h還想知道當前城市a受損的次數

作為遊戲的開發者之一,你有義務回答小h的問題

第1行,兩個整數n(1≤n≤750000)、q(1≤q≤750000)

第2~n行,每行兩個整數表示樹上的一條邊

第n+1~n+q行,每行乙個整數,表示小h這次轟炸的城市

輸出q行,每行乙個整數表示這一次轟炸的城市在此次轟炸後共計受損幾次

輸入

4 41 2

2 33 412

34輸出1

233

設結點x,我們可以知道結點x受到傷害==爺爺造成的傷害+父親+自己+兄弟+兒子+孫子。我們分三步來計算傷害:

1.爺爺和父親造成的傷害等於在爺爺和父親處投彈的次數,用乙個陣列記錄每個結點投彈次數就可以求出來了。

2.自己和兄弟的傷害,直接求兄弟不好求,我們可以通過父結點受傷來求。用f[fa[x]][1] (fa[x]是x結點的父親)陣列記錄父節點到距離為1的所有子節點造成的傷害,自己和兄弟對自己造成的傷害也就是f[fa[x]][1]的值,每次投彈時f[fa[x]][1]++來維護。

3.兒子和孫子造成的傷害等於兒子和距離為2孫子(孫子找兩次父親)的投彈次數,它是直線傳遞的,只需要用乙個陣列記錄,每次兒子和孫子投彈的時候+1就可以了。

因為不需要遍歷樹,只需要模擬樹形結構,每次向上傳2步值就可以,所以可以不用真的建樹。

#include

using

namespace std;

const

int maxn=

8e5;

int fa[maxn]

,f[maxn][3

],a[maxn]

;int

main()

while

(q--

)else

sum=a[x]

; cout<]+a[fa[fa[x]]]

+sum+f[x][2

]

}return0;

}

牛客演算法周周練2

a 題意 求乙個數的順序和逆序之和。題解 其實就是個閹割版的高精度加法嘛。其實逆序數忽略前導零這個條件是沒有用的,因為順序數不可能有前導零,自然結果也不會有,然後注意下首位進製不取餘。include using namespace std int a 10 b 10 intmain for k j ...

牛客演算法周周練2

題目鏈結 include define sc x scanf lld x define pf printf define rep i,s,e for int i s i e i define dep i,e,s for int i e i s i using namespace std typede...

牛客演算法周練 小H和遊戲(樹上dfs 陣列優化)

題目鏈結 1.題目大意 給出一棵樹,現在如果對乙個節點轟炸一次,那麼和它距離不超過2的節點也會被波及。現在有q q 7e5 次轟炸,問每次被轟炸的後此次轟炸的節點目前為止被轟炸多少次 2.很明顯想到暴力dfs,但是如果只有樹的深度只有2層而且所有子節點均連線在根節點,轟炸q次根節點,時間複雜度達到了...