そしてスーパーピアノ、の三回経験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を返します。 }