(luoguからフェイス質問)
問題の意味の翻訳
N個のノードを有するツリーは、各ノードは、色、各色の数、各ツリーおよびサブツリーの要求最大の色数です。
CI <= N <= 1E5
組み合わせた裸の木の発見的問題。統計は最初の出現回数の最大値を取得するために、再び掃引すると、その後の発生とmxCnt同じ色の数を確認するために、再度それを掃引。ブール配列を無理に勧めするためにも重く、空の貢献息子ライトを宣告偽のノートブール配列で標識されています。
コード:
- 書式#include <iostreamの>
- 書式#include <cstdioを>
- 書式#include <CCTYPE>
- #define MAXN 100010
- 使用して 名前空間stdを、
- テンプレート< 型名T>
- ボイドリード(T&X){
- X = 0。
- チャーCH = GETCHAR()。
- しばらく(!isdigit(CH))
- CH = GETCHAR()。
- しばらく(isdigit(CH))
- X = X * 10 +(CH ^ 48)、CH = GETCHAR()。
- }
- int型のn;
- int型のヘッド[MAXN]、トップ;
- 構造体E {
- 、NXTにint型。
- }エッジ[MAXN << 1]。
- インライン ボイドインサート(INT U、 INT V){
- エッジ[++トップ] =(E){V、ヘッド[U]}。
- ヘッド[U] =頂。
- }
- 息子をINT [MAXN]、サイズ[MAXN]。
- 長い 長いANS [MAXN]。
- ボイドDFS1(INT U、 INT PRE){
- サイズ[U] = 1。
- (用{; iはi =エッジ[I] .nxt [U] I =ヘッドINT)
- int型V =エッジ[I] .TO。
- (V ==前)であれば 続けます。
- DFS1(V、U);
- サイズ[U] + =サイズ[V]。
- もし(サイズ[V]>サイズ[息子[U]])
- 息子[U] = V;
- }
- 返します。
- }
- INT色[MAXN]、CNT [MAXN]、合計。
- int型curSon、mxCnt。
- BOOL VIS [MAXN]。
- ボイドCALC(INT U、 INTプリ、 ブールOP){
- オペアンプ?(++ CNT [色[U]、mxCnt = MAX(mxCnt、CNT [色[U])):(--cnt [色[U]、VIS [色[U] = 偽)。
- (用{; iはi =エッジ[I] .nxt [U] I =ヘッドINT)
- int型V =エッジ[I] .TO。
- (|| == == curson中)であれば
- 持続する;
- CALC(V、U、で)。
- }
- }
- ボイド統計(INT U、 INT PRE){
- もし(CNT [色[U]] == mxCnt &&!VIS [カラー[U]])
- 和+ =色[U]、VIS [色[U] = 真。
- (用{; iはi =エッジ[I] .nxt [U] I =ヘッドINT)
- int型V =エッジ[I] .TO。
- もし(V!=前)
- 統計情報(V、U);
- }
- 返します。
- }
- DSUを(無効INT U、 INTプリ、 BOOL OP){
- (用{; iはi =エッジ[I] .nxt [U] I =ヘッドINT)
- int型V =エッジ[I] .TO。
- もし(V ==事前|| V ==息子[U])
- 持続する;
- DSU(V、U、0);
- }
- もし(息子[U])
- DSU(息子[U]、U、1)= curson息子[IN]。
- mxCnt = 0;
- CALC(INについて、1);
- 統計情報(U、PRE)。
- ANS [U] =合計。
- curSon = 0;
- (もし!上){
- 合計= 0;
- 計算値(0、上、中)。
- }
- }
- {int型のmain()
- (n)を読み出します。
- (のための、iが<= N; I ++ iは1 = INT)
- (色[I])を読み出します。
- あなたと、V。
- 以下のために(1 = I int型、iがn <; ++ I){
- (U)を読んで、(v)を読みます。
- 挿入、(V、U)を挿入(U、V)。
- }
- DFS1(1、0);
- DSU(1、0、1)。
- (のための、iが<= N; I ++ iは1 = INT)
- printf("%I64d"、ANS [I])。
- 0を返します。
- }
この問題のCFの給料だけで爆発すると......