BZOJ 5495:[2019地方チーム関節測定] XOR餃子が持続できるトライ+ヒープ

そしてスーパーピアノ、の三回経験XOR $?$ 

+貪欲ヒープ品質トリプル$?$  

だから、退屈......

コード: 

#include <ビット/ STDC ++。H>     
に#define N 500006    
の#defineっ長い長
の#define setIO(複数可)(S ".IN"、 "R"、STDIN)をfreopenは//、freopenは(S "の.out"、」 「W STDOUT)    
名前空間stdを使用。
チャーBUF [100000]、* P1、P2 *。
#define NC()(P1、P2 == &&(P2 =(P1 = BUF)+関数fread(BUF、1,100000、標準入力)、P1 == P2)EOF:* P1 ++)
LL RD()
{ 
    LL X = 0 ; チャーS = NC()。
    一方、(S < '0')S = NC()。
    一方、(S> = '0')X =(LL)(((X << 2)+ X)<< 1)+ S-'0' 、S = NC()。
    戻り値は、x; 
}                    
名前空間トライ
{       
    INT TOT。
    INT CNT [N * 42]、CH [N * 42] [2]。     
    INT newnode(){リターン++ TOT。     
        int型になりました= X = newnode()、I。
        以下のために(私は40 =; I> = 0; -私は)
        { 
            int型、O =(1LL *(V >> I)&1)。     
            CH [今] [O ^ 1] = CH [事前] [O ^ 1]。
            CH [今] [O] = newnode()。  
            事前= CH [事前] [O]。
            今= CH [今] [O]。   
            CNT [今] = CNT [事前] +1。  
        } 
    }    
    LLクエリ(int型のx、int型Y、LL Z)       
    { 
        LL再= 0。
        私はint型。  
        -のための(I iは= 40; I> = 0)      
        { 
            int型、O =(1LL *(Z >> i)は&1)。   
            IF(CH [X] [O ^ 1] <CH [Y] [O ^ 1])再+ =(1LL << I)、X = CH [X] [O ^ 1]、Y = CH [Y] [ O ^ 1]。
            そうでなければ、X = CH [X] [O]、Y = CH [Y] [O]。           
        }        
        戻り再。  
    }          
}。
構造体ノード
{ 
    INT O、L、R。
    LLのval;  
    int型POS;      
    ノード(INT A = 0、INT B = 0、INT C = 0、LL D = 0、int型のE = 0):O()、L(B)、R(C)、ヴァル(D)、POS( E){}    
    ブール演算子<(ノードB)のconst 
    { 
        戻りb.val>ヴァル。
    } 
}。
PRIORITY_QUEUE <ノード> Q。     
LL A [N]、AR [N]、ID [N]。   
INT RT [N]。        
セット<整数> S [N]。  
<整数> ::イテレータを設定します。   
INTメイン()
{ 
    // setIO( "入力")。  
    INT I、J、N、K、OU = 0。
    N = RD()、K = RD()。                  
    ための式(I = 1; iが<= N; ++ I)   
    { 
        A [I] = RD()^ A [I-1];     
        ID [I] = AR [I] = A [i]は、                     
        トライ::挿入(RT [I-1]、RT [I]、A [I])。       
    }            
    ソート(AR + 1、AR + 1 + N)。   
    ID [I] = LOWER_BOUND(AR + 1、AR + 1 + nは、ID [I]) -アル(iは++; <I = N I = 1の)のため;          
    S [(INT)のID [i]は(i)を挿入する。(; <I = N ++ I I = 1の)のため;   
    以下のための(I = 0; iが<N; ++ I)
    {    
        int型L = I + 1、R = N。  
        LL TMP =トライ::クエリ(RT [L-1]、RT [R]、A [I])。              
        INT IDX = LOWER_BOUND(AR + 1、AR + 1 + N、A [I] ^ TMP)-Ar。              
        int型のPOS = * S [IDX] .lower_bound(L)。         
        q.push(ノード(I、L、R、TMP、POS))。               
    }     
    LL ANS = 0LL。   
    (OU <K)、一方 
    {
        ノードE = q.top()。q.pop();   
            INT IDX = LOWER_BOUND(AR + 1、AR + 1 + N、A [EO] ^ TMP)-Ar。       
        ANS + =(LL)e.val、++ OU。                                          
        int型POS = e.pos。                        
        IF(POS = EL!)                  
        {    
            LL TMP =トライ::クエリ(RT [EL-1]、RT [POS-1]、A [EO])。   
            INT IDX = LOWER_BOUND(AR + 1、AR + 1 + N、A [EO] ^ TMP)-Ar。           
            INT、T = * S [IDX] .lower_bound(EL)。
            q.push(ノード(EO、EL、POS-1、TMP、T))。   
        } 
        IF(POS = ER!)   
        { 
            LL TMP =トライ::クエリ(RT [POS]、RT [ER]、A [EO])。  
            INT、T = * S [IDX] .lower_bound(POS + 1)。                  
            q.push(ノード(EO、POS + 1、ER、TMP、T))。      
        } 
    }
    printf( "%のLLD \ n"は、ANS)。  
    0を返します。
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/11938328.html