タイトル説明
長さnの整数のシーケンスがあると操作の2種類があり:
0 LR:ら、一部の数字を選択するには...それらのXOR和が最大であり、最大値を出力するようにAR。
1 xは:配列の最後にXを追加し、N = N + 1ましょう。
0 LR:ら、一部の数字を選択するには...それらのXOR和が最大であり、最大値を出力するようにAR。
1 xは:配列の最後にXを追加し、N = N + 1ましょう。
エントリー
複数のテストケースがあります。入力の最初の行は、テストケースの数を示す整数T(T≤10)を含みます。
各テストケースのため:
最初の行は、二つの整数N、M(1≤n≤5×105,1≤m≤5×105)、シーケンス内の最初の整数の数及び操作の数を含んでいます。
2行目は、最初のシーケンスを表すn個の整数のA1、A2、...、(0≤ai<230)を含みます。
次のm行の各々は、上記のいずれかの操作を含んでいます。
それは、そのΣn≤106、Σm≤106,0≤x<230保証されます。
そして、操作は暗号化されます。あなたはlastansは、最後のタイプ0の操作に対する回答を示し、最初はゼロである場合には、次のように操作を解読する必要があります。
あらゆるタイプ0動作の場合、L =(Lの排他的論理和lastans)とするMOD N + 1、R =(R XOR lastans)MOD N + 1、次いでL> R場合(L、R)スワップ。
すべてのタイプ1の動作について、X = XのXOR lastansをしましょう。
各テストケースのため:
最初の行は、二つの整数N、M(1≤n≤5×105,1≤m≤5×105)、シーケンス内の最初の整数の数及び操作の数を含んでいます。
2行目は、最初のシーケンスを表すn個の整数のA1、A2、...、(0≤ai<230)を含みます。
次のm行の各々は、上記のいずれかの操作を含んでいます。
それは、そのΣn≤106、Σm≤106,0≤x<230保証されます。
そして、操作は暗号化されます。あなたはlastansは、最後のタイプ0の操作に対する回答を示し、最初はゼロである場合には、次のように操作を解読する必要があります。
あらゆるタイプ0動作の場合、L =(Lの排他的論理和lastans)とするMOD N + 1、R =(R XOR lastans)MOD N + 1、次いでL> R場合(L、R)スワップ。
すべてのタイプ1の動作について、X = XのXOR lastansをしましょう。
輸出
各タイプ0動作のために、ください出力一行における最大のXOR和。
サンプル入力
1
3 3
0 1 2
0 1 1
1 3
0 3 4
サンプル出力
1
3
質問の意味:
クエリ区間[L、R]は最大とXORです。
公式ソリューション:
練習暴力はデータベース区間線形構造を維持することができますが、確かに渡すことができませんでした。
各グループの接頭線形の塩基配列(三角形)、線形性を維持貪欲、右側の位置番号は、可能な限り高い表示
を同時にデジタルに対応する位置を記録するために、時間の新しい番号に挿入されます位置の出現、及び低デジタルプッシュ上の元の位置に元の数の位置よりもさらに右側に新しい数字ならば、時間を見つけるための位置に挿入することができます。
ハイからロートラバーサルに、最大値を選択するときはビット区間の左端の右の数字は尋問に表示され、答えは大きくすることができるならば、それは排他的論理和への答えです。
すべてのリニアグループの場合、それは確かにそれの右側に表示されます高い位置に基づいて、排他的またはデジタルリニアをしていた(またはその位置に挿入されます)ので、実際は明らかに正確です。
リニアグループ:
https://blog.csdn.net/a_forever_dream/article/details/83654397
https://blog.sengxian.com/algorithms/linear-basis?tdsourcetag=s_pctim_aiomsg
#include <ビット/ STDC ++ H> の#defineは長い長いllの 使用 名前空間STDを、 CONSTの INT N = 5E5 + 10 。 INT T、N、M。 int型 P [N]、[ 31 ]、POS [N] [ 31 ]。 ボイド追加(INTヴァル、int型X) { ため(int型 i = 0 ; iは<= 30、P [X] [I] = P [X - ; iは++)1 ] [i]は、POS [X] [I] = POS [X- 1 ] [i]は、 int型になりました= X; 以下のために(int型私は= 30 ; i>を=0 ; i-- ) 場合(ヴァル&(1 << I)) { もし!(P [X] [I]) { P [X] [I] = ヴァル。 POS [X] [I] = 今。 破ります; } もし(POS [X] [I] < 今)スワップ(P [X] [I]、ヴァル)、スワップ(POS [X] [i]が、今)。 ヴァル ^ = P [X] [I]; } } int型の照会(int型 L、int型R) { int型 RET = 0 。 以下のための(int型 J =30 ; J> = 0 ; j-- ) 場合(POS [R] [J]> = L &&(RET ^ P [R] [J])> RET)RET ^ = P [R] [J]。 リターンRET; } int型のmain() { // freopenは( "1.in"、 "R"、STDIN)。 // freopenは( "1.out"、 "W"、STDOUT)。 scanf関数(" %のD "、&T)。 一方、(T-- ) { scanf関数(" %d個の%のD "、&N、&M)。 int型のOP、X、L、R。 { scanf関数(" %のD "、&x)は、 (X、i)を追加します。 } INT lastans = 0 。 一方、(M-- ) { scanf関数(" %のD "、&OP)。 もし(OPの== 0 ) { scanf関数(" %dの%のD "、&L&R)。 L =(L ^ lastans)%N + 1 。 R =(R ^ lastans)%N + 1 。 場合(L> R)スワップ(L、R)。 lastans = クエリ(L、R)。 printf(" %d個の\ n " 、lastans)。 } 他 { scanf関数(" %のD "、&x)は、 X ^ = lastans。 N ++ ; (X、n)を加えます。 } } } // FCLOSE(STDIN)。 // fcloseを(標準出力)。 リターン 0 ; }