白魔法師 牛客小白月賽25

2021-10-06 08:42:07 字數 1671 閱讀 6872

對於這個題目,我的做法是換根dp, 因為可以選擇將某乙個點染成白色(不論之前的點是黑是白) , 做法如下:

將每個點當成根節點, 然後將根節點染成白色, 完全符合題意;;

首先dfs一下, 自底向上,求出每乙個點在子樹內的白色連通塊大小。

然後從上到下開始算對孩子節點的貢獻::

如果當前點是黑色, 那麼對兒子節點肯定沒有貢獻 , 因為上面的所有節點都被這個黑色節點隔開了,下面的節點不能和上面的節點連線;

如果當前節點是白色 :

如果孩子節點是黑色, 那麼在第一次dfs的時候,孩子節點肯定對這個父親節點沒有貢獻, 那麼就當前節點對孩子節點直接傳遞下去dp[u]

如果孩子節點是白色, 那麼在第一次dfs的時候,孩子節點肯定對這個父親節點有貢獻, 那麼當前節點對孩子節點的貢獻就是dp[u] - dp[x] ,剪掉孩子的貢獻, 避免重複計算

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#pragma gcc optimize(3 , "ofast" , "inline")

using

namespace std ;

typedef

long

long ll ;

const

double esp =

1e-6

, pi =

acos(-

1);typedef pair<

int,

int> pii ;

const

int n =

1e6+

10, inf =

0x3f3f3f3f

, mod =

1e9+7;

intin()

while

(isdigit

(ch)

) x = x *

10+ ch -

48, ch =

getchar()

;return x * f ;

}int col[n]

, dp[n]

, n ;

vector<

int> v[n]

;void

dfs(

int u ,

int f)

return;}

int ans =0;

void

dfs1

(int u ,

int f ,

int sum)

}int

main()

dfs(1,

0);dfs1(1

,0,0

);cout << ans << endl ;

return0;

}/*13wbwwbbbbbwwwb

1 21 3

2 42 5

3 63 7

5 88 10

8 11

7 99 12

9 13

4*/

藍魔法師 牛客

將一顆 n 1 leq n leq 2000 個結點的樹,分成 t 1 leq t leq n 個連通塊,且每個連通塊的大小都小於或者等於 k 1 leq k leq 2000 求劃分方案數?dp i j 以 i 為根的子樹向父親結點 u 提供 j 個點的貢獻 dp fa i cnt 1 cnt 2...

牛客小白月賽25

分情況討論 include using namespace std const int n 2e5 5 typedef long long ll int a n int main void if n x else printf lld n ans return0 用字元陣列來模擬棧 include ...

牛客Wannafly挑戰賽27 A 灰魔法師

感謝大佬 講解非常仔細 做題的時候也有想過去打表,然後就沒有了,還是沒有找到其中的規律。這裡補一條完全平方數的定義?這個數開根號後是整數如 9,25,36 因為題目資料是1e5,所以兩個數相加也只有2e5,從1到2e5滿足條件的完全平方數個數也只有400 就用乙個陣列去記錄下來,然後for迴圈把給出...