「ブラシのタイトル」ラッキーナンバー

リニアグループの正の解。

一般LCAおよびプレFとして[X] [i]はiがルートにステップと直鎖状の基を歩く$ X $ 2 ^までxは、

それは処理され、組み合わされ、線形ベースパスを取得するためにLCAのようにしてもよいです。

に進む前に。

しかし、私はしばしば前に、そして最終的にmemsetのATに変更したのに長い時間のための制御のmemset、カードカードを持っていません。

多くの場合、本当に嫌なカード。

 

#include <iostreamの> 
する#include <cstdioを> 
する#include <CStringの> 
する#include <cmath>
 の#defineクリア(A)のmemset((A).D、0、はsizeof((A).D))
 使用して 名前空間STDを、


typedefの長い 長いLL。
const  int型 MAXN = 2E4 + 5 
LLのN、Q、X、Y。
【MAXN、W LL。
チャーのxB [(1 << 15)+ 10 ]、* XS = xBで、* = xTのxBの;
#define GTC(XS == xTの&&(Xtが=(XS =のxB)+関数fread(xBで、1,1 << 15、STDIN)、XS == xTの)0:* XS ++)
インラインボイドリード(LL&X) { 
  登録チャー CH = GTC。
  (X = 0 ; CH < ' 0 ' || CH> ' 9 ' ; CH = GTC)。
  (; CH> = ' 0 ' && CH <= ' 9 ' ; X =(X << 1)+(X << 3)CH- + ' 0 '、CH = GTC)。
} 
インラインボイドプリント(LLのX)
{ 
    場合(X < 0){のputchar(' - ')。X = - X;}
     もし(X>)プリント(X / 10 )。
    putchar(X10 + 48 )。
    返します
} 
構造体道路{
     int型の TOT、T [MAXN << 1 ]、NXT [MAXN << 1 ]、最初の[MAXN]。
    ボイド追加(int型のx、int型のY)
    { 
        T [ ++ TOT = Y。
        NXT [TOT] = 最初の[X]。
        最初の[X] = TOTは、
    } 
} EAGE。
構造体Least_Common_Ancetor {
     構造体line_bsis { 
        LLのD [63 ]。
        ボイドインサート(LLのX)
        { 
            ため(登録をint = I 61、I> = 0 ; i-- もし((X >> I)&1 
                { 
                    場合(!D [i])と{D [I] =バツ; ブレーク;} 
                    X ^ = D [i]は、
                } 
        } 
        LLミリアンペア()
        { 
            LL ANS = 0 ため(登録をint iは= 61、I> = 0 ; i--であれば((ANS ^ D [I])> ANS)
                    ANS ^ = [I] D。
            戻るANSを。
        } 
    } LB [MAXN] [ 30 ]、自[MAXN]、TMP、R。
    int型 P、D [MAXN]、F [MAXN] [ 30 ]。
    インラインline_bsisマージ(CONST line_bsis&、CONST line_bsis&B)
    { 
        クリア(R)
        ため(登録をint iは= 60、I> = 0 ; i-- 
        { 
            場合(AD [i])とr.insert(AD [I])。
            もし(BD [I])r.insert(BD [I])。
        } 
        戻りR。
    } 
    インラインボイド lmerge(line_bsis&、line_bsis&B)
    { 
        ため(登録をint i = 60 ; I> = 0 ; - I)
             であれば(BD [i])と
                a.insert(BD [I])。
    } 
    ボイドのinit()
    { 
        Pの =のLOG2(N)+ 1 以下のためにint型 I = 1 iが++; iが<= N 自身の[I] .insert(W [I]))。
        DFS(10);
    } 
    インラインボイド DFS(int型のx、int型FA)
    { 
        ためINT I = eage.first [X]; I; I = eage.nxt [I])
             であれば(!eage.t [I] = FA)
            { 
                int型 T = eage.t [I]。
                D [T] = D [X] + 1 
                F [T] [ 0 ] = xを、LB [T] [ 0 ] = マージ(自[x]は、自身の[T])。
                INTの J = 1 ; J <= P; J ++ 
                { 
                    F [T] [J] = F [F [T] [J =1] [J- 1 ]。
                    もし(F [T] [j] == 0ブレーク
                    LB [T] [J] =マージ(LB [T] [J- 1 ]、LB [] T [F [J- 1 ]] [J- 1 ])。
                } 
                DFS(T、X)。
            } 
    } 
    インラインINT LCA(int型のx、int型のY)
    { 
        クリア(TMP)。
        もし(D [X] < D [Y])スワップ(X、Y)
        INT T = D [X] - D [Y]。
        以下のためにint型 I = Pを; T; i--であれば(T&(1 << I))
            { 
                lmerge(TMP、LB [X] [I])。
                X = F [X] [i]は、T ^ =(1つの << I)。
            } 
        もし(x == y)は戻りX。
        以下のためにint型 = P Iを、I> = 0 ; i-- であれば(F [X] [I] ^ F [Y] [I])
            { 
                lmerge(TMP、LB [X] [I])。
                lmerge(TMP、LB [Y] [I])。
                X = F [X] [i]は、Yは= F [Y]を[I]。
            } 
        lmerge(TMP、LB [X] [ 0]); 
        lmerge(TMP、LB [Y] [ 0 ])。
        戻り [X] [F 0 ]。
    } 
} ZT。
INT メイン()
{ 
    (n)を読み出す;(Q)を読み込みます。
    以下のためにint型 i = 1 ; iが<= N; iは++ )読み出す(W [I])。
    以下のためにint型 I = 1 ; I <= N- 1、I ++ 
    { 
        (X)を読み出し、読み出され(y)を、
        eage.add(X、Y); eage.add(Y、X)。
    } 
    zt.init()。
    / * ため(; iがn = <; I = 1 int型I ++)
        のための(INT J = 0であり、j <= zt.p; J ++)
            COUT << I << ":" << J <<」「<< zt.lb [I] [J] .ma()<< ENDL。* /
    (q-- 
    { 
        (x)を読み出す;(y)を読み出します。
        もし(x == y)は
        { 
            プリント(zt.own [X] .ma());プット("" )。
            続け; 
        } 
        zt.LCA(X、Y)
        印刷(zt.tmp.ma());プット("" ); 
    } 
    戻り 0 
}
ラッキーナンバー

 

おすすめ

転載: www.cnblogs.com/Lrefrain/p/11222907.html