問題の意味:二つの操作のシーケンス所与は、範囲[L、R] XORと最大間隔、及び末尾に番号を追加することを求めます
アイデア:力によって、各グループの値を保存するには、グループ番目の線形Rを検索するために直接次線形であるが、保持時間はLよりも大きい場合、配列が挿入POSの数を表す新しいタイムスタンプ、挿入しますその後、時間が直線要素群が最新であることを保証するために、使用前に交換した後に交換することができる場合、即ち、直接に直接挿入することができます。
書式#include <cstdioを> する#include <iostreamの> の#include <アルゴリズム> 書式#include <CStringの> の#include <cmath> の#include <スタック> の#include <cstdlib> 書式#include <キュー> の#include < 設定 > 書式#include < 文字列。 H> の#include <ベクトル> の#include <両端キュー> の#include <地図> 使用して 名前空間STDを、 #define INF 0x3f3f3f3f3f3f3f3f の#define INF 0x3f3f3f3f の#define EPS 1E-4 の#defineprintfのバグ( "*************************************** \ N-") の#defineデバッグ(X)X COUT <<# "=" << << X "]" << ENDL typedefの長い ロングLL; typedefのロング 長いLL; のconst int型 MAXN = 1E6の+ 5。 、 CONST INT MOD = 998 244 353 ; int型 SUM [MAXN] [ 50 ]、POS [MAXN] [ 50 ]; // SUMデジタルアレイ、POSアレイ時刻一MAXNの合計直鎖状基、合計は[i] [j]は線形イルi番目の意味 のint TOTを; // タイムスタンプが 無効追加(INT NUM){ TOT ++を、 ため(INT I = 0 ;私は< 32 ; I ++){ // 各時間における予約線形基 SUM [TOT] [I] = SUM [TOT - 1 ] [I]、 POS [TOT] [I] = POS [ TOT - 。1 ] [I]は; } intです今= TOT; // 現在のタイムスタンプ のための(int型 I = 32 ; I> = 0 ; i-- ){ IF(&NUM(1LL << I)){ // それに直接挿入することができる IF(SUM [TOT] [I] == 0 ){ SUM [TOT] [I]は = NUMと、 POS [TOT] [I]= 今; BREAK ; } IF(今> POS [TOT] [I]){ // 挿入前に既にの現在の数は、交換する必要その後、存在する場合 スワップ(今、POS [TOT] [I]); スワップ( NUM、SUM [TOT] [I]); } NUM ^ = SUM [TOT] [I]; } } } int型クエリ(INT L、INT R){ // 直接アクセスグループ線形であるR INT ANS = 0 ; のため(int型私= 32 ; I> = 0 ; i--){ //現在のタイムスタンプは、多数の比Lを表示 IF(POS [R&LT] [I]> = L) ANS = MAX(ANS、ANS XOR SUM [R&LT] [I]); } 戻りANSを; } int型のmain(){ INT T; scanfの(" %のD "、&T)、 一方(T-- ){ TOT = 0 ; int型 lastans = 0 ; int型N-、M; scanfの(" %のD%のD "、およびN-、&M)。 int型NUM; 用(int型私= 0 ; 私は、n <; 私は++ ){ scanf関数(" %のD "、およびNUM)を、 (NUM)を追加します。 } 一方(M-- ){ int型のOP、L、R。 scanf関数(" %のD "、&OP)。 もし(OPの== 0 ){ scanf関数(" %dの%のD "、&L&R)。 L =(Lの排他的論理和lastans)%N + 1 。 R =(R XOR lastans)%N + 1; 場合(L> R)スワップ(L、R)。 lastans = クエリ(L、R)。 printf(" %d個の\ n " 、lastans)。 } 他{ scanf関数(" %のD "、&R)。 追加(R XOR lastans)。 N ++ ; } } } }