LOJ2330 清華集訓2017 榕樹之心

2022-05-07 19:33:11 字數 1759 閱讀 7659

loj

感性理解一下,榕樹之心最後要停在乙個節點就是要使得它的不同子樹作用效果互相抵消,

而要想使其最後停在乙個點\(x\)的最大困難就是如何消除重兒子的影響最好辦法就是微笑著去面對它

我們要想辦法量化這乙個過程。

令\(cnt_i\)表示\(i\)子樹能自行消化的對數,\(siz_i\)表示\(i\)子樹的大小,\(son_i\)表示節點\(i\)的重兒子,那麼乙個點\(i\)能被消掉當且僅當

\[\begin

siz_i\bmod 2 = 1\\

siz_i-siz_\geq siz_-cnt_}

\end

\]這個是怎麼來的呢,

就是說當乙個重兒子的\(siz\)較小時,因為它的\(siz\)還是較其他兒子最大的,所以總可以通過其他子樹來互相消掉;

而乙個重兒子的\(siz\)較大時,其他兒子一起搞不過它,那麼只有它內部打架別人才有可能打得過,而這顯然也有乙個限度。

如何求\(cnt\)可以向上面一樣思考求出。

因為要求每個點所以要換根,對於乙個點\(x\),把根到\(x\)的路徑看作乙個點就可以了,具體實現細節詳見**。

#include #include #include #include #include #include using namespace std; 

inline int gi()

const int max_n = 1e5 + 5;

struct graph e[max_n << 1];

int fir[max_n], e_cnt;

void cleargraph()

void add_edge(int u, int v) , fir[u] = e_cnt++; }

int n;

int siz[max_n], s1[max_n], s2[max_n], cnt[max_n];

bool ans[max_n];

void dfs1(int x, int fa)

if (siz[s1[x]] - (cnt[s1[x]] << 1) <= siz[x] - siz[s1[x]] - 1) cnt[x] = (siz[x] - 1) / 2;

else cnt[x] = cnt[s1[x]] + siz[x] - siz[s1[x]] - 1;

} void dfs2(int x, int fa, int scnt, int pcnt, int ssiz)

int sz, ct, tmp = ssiz + siz[x] - siz[s1[x]] - 1;

if (siz[s1[x]] > scnt) sz = siz[s1[x]], ct = cnt[s1[x]], tmp += scnt;

else sz = scnt, ct = pcnt, tmp += siz[s1[x]];

if (tmp >= sz - (ct << 1) && !((sz + tmp) & 1)) ans[x] = 1;

else ans[x] = 0;

for (int i = fir[x]; ~i; i = e[i].next) else

} }

int main ()

dfs1(1, 0);

dfs2(1, 0, 0, 0, 0);

if (type == 3) printf("%d\n", ans[1]);

else

} return 0;

}

清華集訓2017模擬 ces

首先把用tajan把橋邊全部找出來,橋邊會把圖分成若干個雙聯通分量。把每個雙聯通分量並成乙個點,橋邊作為邊,這會構成一棵樹。顯然,對於每個詢問加k條邊最多能去掉多少條橋邊,就是用k條簡單路徑去覆蓋這棵樹,最多能覆蓋多少條邊。有乙個很優的貪心,把k按1 q做,每次找到樹的直徑,答案加上直徑的長度,把直...

清華集訓2017滾粗記

很早就到了,然後就被眾人教育,晚上連營ak殺被wzd yql教育,去找wyy換衣服又被wyy和dwj教育。虛心接受教育之後就回去了。考得最崩的一天。開場看完題發現t1是個原題加強,t2只會狀壓的部分分,t3是個裸分塊但是要寫挺久的,於是決定先開t1。開了t1半個小時之後發現毫無思路,式子並不能像原題...

清華集訓2017模擬12 09 塔

有乙個塔,他的名字叫做粽粑,粽粑的每一層都有乙個顏色 粽粑非常厲害,它在吸收天地精華之後會長高.粽粑的長高方式有兩種 1.在塔頂長出一層.2.在塔底長出一層,即原來的第一層變成第二層,第二層變成第三層,以此類推,新長出來的是第一層.粽粑有可能在某個時刻不是很開心,這個時候它會撤銷它的前若干次長高.你...