洛谷P4228 清華集訓2017 榕樹之心

2022-05-06 20:00:22 字數 1572 閱讀 5737

先只考慮根節點是否合法。發現兩個來自不同子樹的點可以消去,那麼只需判定所有點能否兩兩消去,使心停留在根節點即可。

發現其可以轉化為乙個模型:有若干個集合,每個集合內有若干個點,每次可以消去兩個來自不同集合的點。設集合點數總和為 \(sum\),最大集合點數為 \(\max\),得:

\(sum-\max \geqslant \max\) 時,即 \(sum \geqslant 2\max\),若 \(sum\) 為偶數則能消完,否則會剩下 \(1\) 個點,消去了 \(\left \lfloor \frac \right \rfloor\) 對。

否則會剩下 \(\max-(sum-\max)\) 個來自最大集合的點,消去了 \(sum-\max\) 對。

然後將該模型應用到本題,設 \(f_x\) 為點 \(x\) 子樹內能最多消去多少對點,點 \(y\) 為點 \(x\) 兒子中子樹大小最大的兒子,得當 \(size_x-1 -size_y\geqslant size_y-2f_y\) 時,\(f_x=\left \lfloor \frac \right \rfloor\),否則 \(f_x=f_y+size_x-1-size_y\)。

然後考慮如何判定其他節點合法,可以看作心先從根節點移動到了當前節點,那麼將根節點到當前節點的鏈縮成乙個點即可。這裡需要知道縮點後的最大子樹,因此還需處理出每個節點的次大子樹。

通過 \(sum \geqslant 2\max\) 是否滿足和總點數與當前節點深度的奇偶性是否相同來判定即可。

#include#define maxn 200010

using namespace std;

templateinline void read(t &x)

while(isdigit(c))

if(flag)x=-x;

}int type,t,n;

int f[maxn],siz[maxn],dep[maxn],son1[maxn],son2[maxn],ans[maxn];

struct edge

e[maxn];

int head[maxn],edge_cnt;

void add(int from,int to)

,head[from]=edge_cnt;

}void dfs1(int x,int fa)

if(!son1[x]) return;

if(siz[x]-1>=2*(siz[son1[x]]-f[son1[x]])) f[x]=(siz[x]-1)/2;

else f[x]=siz[x]-1-siz[son1[x]]+f[son1[x]];

}int c(int x,int y)

void dfs2(int x,int fa,int p)

}void clear()

int main()

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

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

else for(int i=1;i<=n;++i) printf("%d",ans[i]);

putchar('\n');

}return 0;

}

洛谷 P5933 清華集訓2012 串珠子 題解

原題 清華集訓2012 串珠子 加強版 串珠子 加強版 這道題基本思路與之前寫過題解的轟炸方案一樣,可見這是一種常用的套路了。大概翻了翻題解,發現大部分都是用的狀壓dp 列舉子集,時間複雜度 o 3 n 這裡提供乙個 o n 2 2 n 的做法,實測可以在 2s 內通過 n 20 的資料,目前排全站...

(寒假集訓)洛谷 P2058 海港

小k是乙個海港的海關工作人員,每天都有許多船隻到達海港,船上通常有很多來自不同國家的乘客。小k對這些到達海港的船隻非常感興趣,他按照時間記錄下了到達海港的每一艘船隻情況 對於第i艘到達的船,他記錄了這艘船到達的時間ti 單位 秒 船上的乘 客數星ki,以及每名乘客的國籍 x i,1 x i,2 x ...

洛谷P3761 TJOI2017 城市

從加里敦大學城市規劃專業畢業的小明來到了乙個地區城市規劃局工作。這個地區一共有ri座城市,1條高速公路,保證了任意兩運城市之間都可以通過高速公路相互可達,但是通過一條高速公路需要收取一定的交通費用。小明對這個地區深入研究後,覺得這個地區的交通費用太貴。小明想徹底改造這個地區,但是由於上司給他的資源有...