2019頭の牛のオフより学校第四のセグメントツリー&& B xor--リニア基本給

問題の意味

あなたは$ N $のセットを与え、各セットには、いくつかの整数が含まれています。私たちは、コレクションがあれば整数を表しているとし、その排他的または整数に等しいのサブセットが存在する場合にのみ、と言います。各セットの$器R $から$ lの$は$ xに$を表現することができれば今、あなたは、一度に答えるために$ M $($のL、R、X $を)尋ね必要です。

分析

各セットの線形群を得るために、クロスセグメントツリーを有する直鎖状の基を維持するために、参照コード

#include <ビット/ STDC ++ H>
 の#define REGレジスタ
 使用 名前空間STDを、
typedefの長い 長いLL。

CONST  INTビット= 31 const  int型 MAXN = 100000 + 10 INTのN、Q。
LL [MAXN] [ 32 ]。

構造体LBASE {
     // CONST静的INTビット= 31。   // 0〜31位 
    のLL D [ビット+ 1 ]、TMP [ビット+ 1 ]。   // 线性基
    ブールフラグ=  ;  // 记录是否CNT <N 
    LBASE(){memsetの(D、0はsizeofのD);}
     ボイド挿入(LLのX)
    { 
        ためint型 I =ビット;〜I; i-- であれば(X&(1LL << I))
            { 
                場合(D [i])と{D [i]は= xで!。破る;}
                    のx ^ = D [i]は、
            } 
       フラグ = 
    } 
    ブールチェック(LL X)   // 返回真表示已经能被表示
    {
         ためint型 I =ビット; iは〜; i--であれば(X&(1LL << I))
            { 
                場合(D [i])と!返し のx ^ = D [i]は、
            } 
        を返す 
    } 
    LL Qmaxの(LL RES = 0 
    { 
        ためint型 I =ビット;〜I; i-- 
            RES = MAX(RES、RES ^ D [I])。
        リターンのres; 
    } 
    LL Qminを()
    { 
        場合(フラグ)戻り 0 ;
        以下のためのint型 I = 0 ; I <=ビット; iが++ 場合(D [i])とリターンD [i]は、
    } 
    LLクエリ(LL kの)   // 查询第K小
    { 
        LL RES = 0int型 CNT = 0 ; 
        K - =フラグ。もし(!k)のリターン 0 ;
        以下のためにint型 i = 0 ; I <=ビットiが++ ){
             ためINT J = I- 1 ;〜J; j-- 場合(D [i]が&(1LL << J))D [i]は^ =D [J]。
            もし(D [i])とTMP [CNT ++] = D [i]は、
        } 
        もし(K> =(1LL << CNT))リターン - 1 以下のためにint型 i = 0 ; iは、CNT <; iは++ 場合(K&(1LL << I))RESは^ = TMPを[I]。
        リターンのres; 
    } 
    ボイドマージ(CONST LBASE&A){    // 求并集
        のためのint型 = iビットを、I> = 0 ; - i)が
             あれば(広告が[I])を挿入(AD [I])。
    } 
}。

LBASE交差点(CONST LBASEと、CONST LBASE&B)   // 求交集
{ 
    LBASE ANS、C = B、D = B。
    以下のためにint型 i = 0 ; I <=ビット; iは++ 
    { 
        LL X = AD [i]は、
        もし(!x)を継続int型 J =; LL T = 0 ;
        (; J> = 0 ; - j)の
         場合((X >> J)&1 であれば(CD [J]){X ^ = CD [J]; T ^ = DD [J];}
         そう ブレイク;
        もし ans.d [I] =(X!)T。
         {CD [J] = xと; DD [J] = T;} 
    } 
    戻りANS。
} 

構造体SegTree 
{ 
    LBASEのB [MAXN << 2 ]。
    ボイドビルド(int型、O INTの L、INT R)
    { 
        int型 M = Lの+(RL)/ 2 場合(L == R)
        { 
            ためint型 i = 0 ; iは< 32 ; iは++ )B [O] .insert([L] [I])。
        } 
        
        { 
            (ビルド2 *のO、L、M)を、
            ビルド(2 * + O 1、M + 1 、R&LT);
             // B [O] .merge(B [2 * O]); B [O] .merge(B [2 * + O. 1]); 
            B [O] =交点(B [ 2 [*のO]、B 2 * + O 1 ]); 
        } 
    } 

    // [QL、QR] Xで示すことができるかどうかを確認
    BOOLクエリ(INT O、INT L、INT R&LT、INT QL、INT QR、LL X)
    { 
        int型 M = Lの+(R&LT - L)/ 2 BOOL FLAG1 = 、FLAG2 = ;
        もし(QL <= L && R <= QR)   リターンB [O] .check(X)。
        もし(QL <= M)FLAG1 =クエリ(2 *のO、L、M、QL、QR、X)。
        もし(QR> M)FLAG2 =クエリ(2 * O + 1、M + 1 、R、QL、QR、X)。
        戻る FLAG 1 && FLAG2を。
    } 

} SEG。

INT メイン(){ 
    scanf関数(" %d個の%のD "、&​​N、&Q)。
    以下のためのint型 I = 1; iが<= N; iは++ 
    { 
        int型 SZと、scanf関数(" %のD "、&SZ)。
        INT J = 0 ; J <SZ、J ++)のscanf(" %のLLD "、および[I] [J])。
        INT ; J <J = SZ 32 ; J ++)[I] [J] = 0 ; 
    } 
    seg.build(11 、N)
    一方、(q-- 
    { 
        int型のL、R。LLのx; 
        scanf関数(" %D%D%LLD "、&​​L&R&バツ);
        もし(seg.query(11、N、L、R、X))のprintf(" YES \ n " );
           のprintf(" NO \ nを" ); 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/lfri/p/11280505.html