CSP2019 樹的重心 解題報告

2022-04-07 10:22:37 字數 2259 閱讀 7182

[csp2019] 樹的重心

\(t\) 組資料 \((1 \le t \le 5)\), 每次給定一棵 \(n\) 個點的樹 \((1 \le n \le 299995)\).

設 \(e\) 為樹的邊集, \(v'_x,\ v'_y\) 分別為刪去邊 \((x,y)\) 後 點 \(x\) 所在的點集和點 \(y\) 所在的點集.

求\[\sum_ \left( \sum_ [x 是 v'_x 的重心] * x + \sum_ [y 是 v'_y 的重心] * y \right)

\]暴力列舉每一條邊, 求重心即可.

做法 1

總的思路是從列舉邊變為列舉點,

具體操作 :

列舉每乙個點 \(u\), 對該點的每一棵子樹都處理出 \(w_i\) 表示, 該子樹內權值為 \(i\) 的邊的個數,

這裡邊的權值定義為 : 以 \(u\) 為根節點時, 刪去這條邊後, 刪掉的節點個數.

再分類討論當前列舉到的子樹是不是權值最大的子樹, 找到乙個區間 \([l,r]\), 使刪去的邊的權值 \(e_i \in [l,r]\) 時, 點 \(u\) 為新樹的重心, 用樹狀陣列區間求和即可.

問題在於, 我們每次要獨立地獲得每個子樹的邊的數量, 所以就要用到線段樹合併或者主席樹, 不然的話每次重新獲取子樹的邊的複雜度會達到 \(o(n^2)\), 然後本人線段樹合併與主席樹都不會, 所以....

做法 2

總思路: 利用倍增優化找重心的過程.

突破口: 樹的重心一定在根節點的重路徑上.

證明:

定義 \(son[u]\) 為節點 \(u\) 的重兒子.

設該樹的根節點為 \(t\), \(v,\ u\) 為該樹上的兩個節點, 且 \(fa[v]=u\), \(v \not = son[u]\).

反證法: 假設 \(v\) 為以 \(t\) 為根節點的樹重心,

則 $ sz[t]-sz[v] \le \frac $,

所以 $ sz[v] \ge \frac $.

設 \(p\), 滿足 \(fa[p]=u\), 且 \(p \not = v\),

則 \(sz[p] \le sz[u]-1-sz[v] \le sz[u]-1-\frac \le sz[t]-1-\frac \le sz[v]\)

所以 \(v\) 為 \(u\) 的重兒子, 產生矛盾, 假設不成立,

得證.具體做法:

設 \(s[u][i]\) 為從節點 \(u\) 沿著重路徑往下跳 \(2^i\) 步後到達的點.

設 \(t\) 為當前樹的根節點.

當 \(sz[s[u][i]] > \frac\) 時, \(u=s[u][i]\),

不斷往下跳, 直到找到第乙個有可能成為重心的點, 然後判斷這個點以及它的重兒子是不是重心 (因為一棵樹最多只能由兩個重心, 所以只需判斷這兩個點), 若是, 則加入答案中.

首先, 我們隨便找乙個點作為根節點, 那麼這裡我們預設選擇 \(1\) 號點.

然後, 對於每乙個節點, 我們列舉它連向子節點的每一條邊, 然後分類討論, 重新選擇 \(u\) 的重兒子 (詳見**).

總時間複雜度 \(o(n\log n)\)

#include#define ll long long

using namespace std;

const int n=299995+7;

const int l=20;

int t,n,sz[n],son[n][2],s[n][l+7];

ll ans;

int lst[n],nxt[2*n],to[2*n],tot;

void add(int x,int y)

void rfs(int u)

void pre(int u,int fa)

else if(sz[v]>sz[son[u][1]]) son[u][1]=v;

} sz[u]++;

rfs(u);

}void find(int u)

void run(int u,int fa)

son[u][0]=t1; // 還原

sz[u]=t2;

rfs(u); //更新

}int main()

pre(1,0);

run(1,0);

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

} return 0;

}

CSP2019樹的重心

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

CSP2019 樹的重心

點這裡看題目。原來資料的奇怪結尾就可以拿來判斷特徵呀 太簡單就不說了。考慮完全二叉樹怎麼做。這裡需要注意一點,就是 n 262143 2 1 也就是說,資料實際上就是一棵滿二叉樹。由於滿二叉樹具有極強的對稱性,我們不難想到這樣解決 首先,答案一定包含 frac rt 其中 rt 是樹的根。考慮根的左...

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

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