nitacm 2019学校の人種Eさんレイトンとバランスのとれたツリー(互いに素セットメンテナンス)

トピックリンク:https://ac.nowcoder.com/acm/contest/2995/E

質問の意味:

パス内のすべてのポイントに簡単に右からV Uから木、バランスの最大値と最小値との差(U、V)。

T基(T <= 10)、N(1 <= N <= 5E5)、N A [i]が(1 <= A [i]の<= 1E9)、uとv番目の点の右、N-1を表します。 Uを表し、Vは、ツリー構造を確保するために、二つの接続端部を有しています

バランス%の1E9の木を求めて

例:

答えは179です 

ソリューション:

最大値と最小値を算出しました。

最大値を選択する方法であって、各ブロックユニコムのサイズを維持しながら、チェックのセットで一般からのドットのそれぞれと接続するとは、この点について明確にパスの最大数として計算することができます。

最小値の計算と同様の方法。

 

アイデア:

プレスポイントの最大重量を計算

ポイント:4,5,6,8,9,3,10,7,1,2

ポイント右:2,4,5,5,5,6、6,8,9,9

④1に設定VIS最初のポイントは、アクセス権を持って、すべてのポイントを介してアクセスポイントに接続されている④、見つかりませんでした。

次いで、1点⑤VISセット、アクセス権を持って、すべてのポイントを介してアクセスポイントに接続されている⑤、ポイントを見つけるには④、この時点で次のように処理される必要があります。

④ポイント通信リンクブロック(SIZE1合計点)、2点の最大量を有し、そしてポイント⑤ブロック通信リンク(size2に点の合計)は4点の最大重量であります

左ブロックユニコムからの任意の点を取る、中国ユニコムのブロックのいずれか2点間の最大点の右側を右点を取る4を乗じ* size2に点、⑤右点SIZE1の合計、4であり、この部分が最大であります値

そして、2つのブロックの労働組合は、(互いに素セットメンテナンスに)サイズを再計算し、ポイントソートを右小から大へのポイントであるので、重要どのように多くのではありませんをブロックする権利は、大きなポイントで乗算されています。

 

右のすべての点と、回答減算である逆の順序でMAX、MIN算出したポイントを右に、算出した後。

 

スタブ(*¯▽¯*)oを添付コード:

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
const  int型 MAXN = 5E5 + 10 const  int型 MOD = 1E9 + 7 整数nは、FA [MAXN]、サイズ[MAXN]、VIS [MAXN]。 < INTINT > [MAXN]。
ベクター < INT > G [MAXN]。

ボイドのinit()
{ 
    INT iは= 1 ; iが<= N; I ++)FA [I] = I、サイズ[I] = 1 
    memsetの(VIS、0はsizeof VIS)。
} 
int型 取得INT X)
{ 
    場合(FAを[X] == x)をリターンX。
    リターン FA [X] = GET (FA [X])。
} 
ボイドマージ(int型 A、int型B)
{ 
    A = GET ()。
    B = GET (B);
    もし(!= B)
    { 
        FA [A] = B。
        サイズ[B] + = サイズ[A]。
     } 
} 

int型のmain()
{ 
    int型T。
    scanf関数(" %dの"& T)、
     一方(T-- 
    { 
        scanf関数(" %のD "& n)は、
        INIT()
        のためにINT iは= 1 iが<= N; I ++ 
        { 
            scanf関数(" %dを、 &[i]の1次回); 
            [i]は.second = I; 
            G [i]が.clear(); 
        } 
        のためのINT iは= 1 ; I <N; I ++ 
        { 
            int型、U、V; 
            scanf関数(" % D%D"、&​​U&V); 
            G [U] .push_back(V); 
            G [V] .push_back(U); 
        } 
        ソート( + 1、+ 1 + n)は、
         長い 長い ANS = 0 ;
         のためのINT私は= 1 ; I <= N; I ++ 
        { 
            int型今= [I] .second; 
            VIS [今] = 1 ;
             のためのINT J:G [今])
            { 
                場合(VIS [J])
                { 
                    ANS=(ANS +(1LL * [i]が1次回*サイズ【今】%MOD)*サイズ[ 取得(J)]%MOD)%のMOD。
                    (今、j)をマージします。
                } 
            } 
        } 
        
        のinit(); 
        INT I = N; I> = 1 ; i-- 
        { 
            int型今= [I] .second。
            VIS [今] = 1 INT :G [今] J)
            { 
                場合(VIS [J])
                { 
                    ANS =(ans-(1LL * [i]が1次回*サイズ【今】%のMOD)*サイズ[ GET(J)]% MOD + MOD)%モッズ; 
                    (今、j)をマージします。
                } 
            } 
        } 
        のprintf(" %のLLD \ n " 、ANS)。
    } 
    戻り 0 
}

 

wa了几发,

リターンFA [X] = GET(FA [X]);写成戻りGET(FA [X])。

G [i]は、ライト・クリア(ありません)

......

おすすめ

転載: www.cnblogs.com/myrtle/p/12046384.html