問題の意味
あなたは$ 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 = 0。int型 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(1、1 、N) 一方、(q-- ) { int型のL、R。LLのx; scanf関数(" %D%D%LLD "、&L&R&バツ); もし(seg.query(1、1、N、L、R、X))のprintf(" YES \ n " ); 他 のprintf(" NO \ nを" ); } 戻り 0 。 }