CSP S 2019 樹的重心 重心

2022-05-09 16:07:11 字數 1973 閱讀 5828

題意:給定一棵樹(測試資料中樹的結點數中告知),求斷掉每條邊兩棵子樹所有重心的編號和之和。

題解:重心 + 樹狀陣列

先隨便求個重心出來,記做\(k\)。子樹大小記為\(sz\),子結點子樹大小的最大值記為\(mx\),考慮乙個結點\(u\not = k\):

首先,割掉一條邊使得\(u\)成為所在連通塊的重心,這條邊一定不在\(u\)子樹內。原因很簡單,考慮若\(u\)在\(k\)的\(v\)方向的子樹中,把\(u\)子樹中一條邊刪去後,\(sz[v]\)會減小,那麼重心\(k\)會往非\(v\)方向偏移或者不動,但絕不會進入\(v\)子樹。

然後再考慮刪去的子樹應滿足什麼條件。容易發現是否合法只與子樹大小有關:我們得保證與\(u\)相連的子樹都滿足大小不超過連通塊大小除以\(2\)這個條件。令\(s\)為刪去的子樹(與\(u\)不連通的子樹)大小,條件形式化即為:

\[2\times mx[u]\leq n-s\\

2\times(n-s-sz[u]) \leq n-s

\]解出

\[s \in[n - 2\times sz[u], n-2 \times mx[u]]

\]再補上條件,刪掉的邊不在\(u\)子樹中。

這個怎麼求呢?看起來可以無腦主席樹,但是有更好的做法:

一條邊\((u,fa[u])\),\(sz[u]\)對\(u\)子樹外有貢獻,\(n-sz[u]\)對\(u\)子樹內有貢獻,\(sz[u]\)對\(u\)的祖先結點有負的貢獻。

對於第乙個,把所有的貢獻加入樹狀陣列,到進入\(u\)的時候把貢獻去掉,離開\(u\)是把貢獻加上。

對於第二個,進入\(u\)的時候把貢獻加入,離開\(u\)是把貢獻去掉。

對於第三個,記錄進出\(u\)貢獻的增量,把

一、二的貢獻減去這個增量,就是\(u\)作為重心的次數。

最後考慮\(u=k\)的情況:

設最大兒子是\(v\),次大兒子是\(v'\),則可以分兩類:

dfs的時候記錄一下即可。

**皮了一下。

#include #include #include #define pb push_back

using namespace std;

typedef long long ll;

const int n = 3e5 + 5;

int n, rt, sz[n], mx[n], son1, son2;

vectorg[n];

ll ans;

struct bit

void clear()

void add(int u, int v)

}int qry(int u)

return ans;

}int qry(int l, int r)

} *b1 = new bit, *b2 = new bit;

void dfs(int u, int fa = 0)

if(n - sz[u] > n / 2) tg = 0;

if(tg && !rt) rt = u;

}bool s1[n];

void dfs2(int u, int fa = 0)

for(int i = 0; i < (int) g[u].size(); i ++)

if(u != rt)

}int main()

rt = 0; dfs(1); dfs(rt);

ans = 0;

for(int i = 1; i <= n; i ++) if(i != rt)

son1 = son2 = 0;

for(int i = 0; i < (int) g[rt].size(); i ++) else if(sz[v] > sz[son2])

}dfs2(rt);

printf("%lld\n", ans);

b1->clear(); b2->clear();

}return 0;

}

CSP S2019 D2T3 樹的重心

小簡單正在學習離散數學,今天的內容是圖論基礎,在課上他做了如下兩條筆記 乙個大小為 n nn 的樹由 n nn 個結點與 n 1 n 1 n 1 條無向邊構成,且滿足任意兩個結點間有且僅有一條簡單路徑。在樹中刪去乙個結點及與它關聯的邊,樹將 為若干個子樹 而在樹中刪去一條邊 保留關聯結點,下同 樹將...

CSP2019 樹的重心(樹的重心 倍增 換根)

當年我做這道題時還太嫩了,只能想到暴力。其實如果會了更高的科技這道題只要稍微對暴力優化一下就能ac 我也不會含淚75pts了 廢話不說了,暴力的思路就是列舉每一條邊然後求兩個子樹的重心。直接求重心的複雜度是 o n 的,我們考慮優化到 o log 我們想要求以 x 為根的子樹的重心,首先有個引理 這...

CSP2019樹的重心

題解 csp2019d2t3 首先我們要明確乙個性質,那就是對於一棵樹的任何乙個節點來說,如果這個點不是重心,那麼這棵樹的重心就一定在這個節點的以重兒子為根節點的子樹裡 證明顯而易見,因為該點不是重心所以siz 重兒子 一定大於 lfloor frac rfloor 另外還有乙個重心的定義 重心所有...