牛客練習賽55(E(換根dp詳解))

2021-10-02 03:25:33 字數 1937 閱讀 8081

牛客練習賽55

e-樹參考題解來自:題目:

但是這個大佬講的不太好理解。

每條邊的貢獻又是怎麼算的呢?

首先這個是很有用的:(a+b+c)*(a+b+c),但是我覺得不能像他那樣拆,要這樣拆:

(a+b+c)*(a+b+c)=a^2+b^2+c^2+2ab+2ac+2bc,為什麼是a+b+c呢?假設你當前列舉的邊算貢獻時,這條邊的權值是b,

那麼a+b+c就是代表著左邊的某個點到該線的距離為a,右邊的某個點到該線的距離為c,那麼三個線段連在一起了答案就是(a+b+c)^2。

(a+b+c)*(a+b+c)=a^2+b^2+c^2+2ab+2ac+2bc   單獨拿出b就是當前線段對答案的貢獻。

也就是b^2+2ab+2bc   其他的當列舉當那個點自然會把答案算上了。

這時,a和c是有多個的也就是下面的多項式:

b^2+2*a[1]*b+2*c[1]*b

b^2+2*a[2]*b+2*c[2]*b

b^2+2*a[3]*b+2*c[3]*b

...

由於邊權都是1  b等於1,化簡就是

1+2*a[1]+2*c[1]

1+2*a[2]+2*c[2]

1+2*a[3]+2*c[3]

...

那麼就得到結論:每條邊的貢獻就是經過這條邊的所有路徑的長度和

為什麼沒有這個乘2呢?我認為的是2*a*b 乙個貢獻是a,另乙個貢獻就是b了,成兩半了。

如何算 經過這條邊的所有路徑的長度和 呢?

其實就是 左邊邊權和 * 右邊點數+右邊邊權和*左邊點數+左邊點數*右邊點數 好好想一想

做法屬於乙個比較巧的做法了吧。。。

然後聯想到如果邊權不是1呢?能這樣做嗎?(我認為不能,只能按題解那樣做法了,題解不知道誰寫的,寫的一堆公式,講的看不懂)

#includeusing namespace std;

typedef long long ll;

const int n=1e6+10;

const ll mod=998244353;

vectorg[n];

ll sz[n];

ll dp[n];

int n;

ll ans;

void dfs1(int u,int fa)

}void dfs2(int u,int fa)

}int main()

dfs1(1,0);

dfs2(1,0);

cout<

return 0;

}

牛客20180601練習賽19 E

已知第i個瓶子的品牌為ai,且其能開啟bi品牌的瓶子.問有幾瓶飲料托公尺無法喝到.被用於開啟飲料瓶的瓶子不一定需要被開啟.乙個瓶子不能開啟其本身.輸入描述 第一行乙個整數n,表示飲料的瓶數.接下來n行,每行兩個整數ai,bi.輸出描述 輸出一行乙個整數,表示小托公尺無法喝到的飲料瓶數.示例1 輸入 ...

牛客網練習賽24 E青蛙

有乙隻可愛的老青蛙,在路的另一端發現了乙個黑的東西,想過去一 竟。於是便開始踏上了旅途 一直這個小路上有很多的隧道,從隧道的a進入,會從b出來,但是隧道不可以反向走。這只青蛙因為太老了,所以很懶,現在想請你幫幫慢,問他最少需要幾步才可以到達對面。將小徑看作一條數軸,青蛙初始在0上,這只青蛙可以向前跳...

牛客練習賽53 A(簡單dp)

超越學姐非常喜歡自己的名字,以至於英文本母她只喜歡 c 和 y 因此超越學姐喜歡只含有 c 和 y 的字串,且字串中不能出現兩個連續的 c 請你求出有多少種長度為n的字串是超越學姐喜歡的字串。答案對1e9 7取模。輸入乙個整數n。1 n 100000輸出乙個整數表示答案。示例1 複製3複製 5cyy...