HDU-6703-配列-2019CCPC試験

I TMは本当に弟です。

質問の意味:

1-Nシリーズの数を与えます

たびに百万の位置の値を置くことができます

または値を見つけるために、すべての[1] ... [r]は配列の数がこの値に等しくすることができない場合、この値W>

その時点でゲームは1つが自閉症でないだろう、木カバーツリーセクションは、最初の大きなKを修復することを確認感じます。

実際には、他の方法ラウンド、[1] ... [R]数列は、その後、実際に、我々は[R + 1] ... [N]からの第1見つけることができ、この値に等しくすることができない場合値> = W

しかし、修正して、この問題を検討し、あなたは場所がもはや貢献を生成し、この値に添加した後、nよりも大きい、この付加価値は非常に大きいでしょう

この値は、削除することと等価です。

私たちは、この値が削除されると、それが答えとして可能であることを意味するので、それらを保存するために、これらの値を考慮してください。

私たちは、木の社長を設立し、クエリが> =数字のワット数と同様に、K上で動作する小さな範囲よりも大きく、実装、および内部にセット番号を削除しています

この値が0、我々は、その答えは、n + 1でない場合は、ワットより大きいがあるかどうかのクエリを削除した数であれば我々はそれ以外の場合は、最初に内部で設定され、範囲内のw> =数を見てワットよりも大きく、番号はLOWER_BOUNDを達成するために使用することができます

0は考慮されていない、我々は最初のr-L + 1 NUMをチェックし(数がNUMより大きい)+これは、> = Wデジタル最初の内部領域内に見出されます

> = 1-R間隔をr + 1> =より良い回答数Wの範囲のN内で削除され、対数比の数であることができるように、数字のセット中のW最初のクエリ

これは、両方の最小値をとります。

書式#include <iostreamの> 
書式#include <stdio.hに> 
する#include < 文字列の.h> 
の#include <アルゴリズム> 
書式#include < 設定 >
 使用して 名前空間はstd;
const  int型 MAXX = 2E5 + 6 構造体ノード{
   int型のL、R。
  int型のCNT; 
}ツリー[MAXX * 40 ]。
int型のルート[MAXX]。
int型のCNT;
設定 < 整数 > 秒;
INT [MAXX]。
のインサート(int型の L、INT R、int型プリ、INT&今、int型のPOS){  = ++ CNT。
     ツリー[今] = ツリー[事前]。
     ツリー[今] .CNT ++ ;
     もし(L == R){
         リターン
     } 
     INT半ば=(L + R)>> 1 もし(POS <= MID){ 
        インサート(L、中間、ツリー[事前] .L、ツリー[今] .L、POS)。
     } { 
        インサート(中 + 1 、R、ツリー[事前] .R、ツリー[今] .R、POS)。
     } 
} 
int型のクエリ(int型の L、INT R、int型の L、int型の R、INT W){
     場合(L == R){
         戻りツリー[R] .cnt- ツリー[L] .CNT。
    } 
    INT半ば=(L + R)>> 1 もし(W <= MID){
         戻りツリー[ツリー[R] .R] .CNTツリー[ツリー[L] .R] .CNT + クエリ(ツリー[L] .L、ツリー[R] .L、L、半ば、ワット); 
    } {
         戻りクエリ(ツリー[L] .R、ツリー[R] .R、中間+ 1 、R、W)。
    } 
} 
int型 K番目(INT L、int型の R、int型の L、int型の R、int型K){
      場合(L == R){
         戻りL。
     } 
     INT半ば=(L + R)>> 1 INT S =ツリー[ツリー[R] .L] .cnt- ツリー[ツリー[L] .L] .CNT。
     場合(S> = K){
         戻りK番目(ツリー[L] .L、ツリー[R] .L、L、中、K)。
     } {
         戻り K番目(ツリー[L] .R、ツリー[R] .R、中間+ 1、R、K- S)を、
     } 
} 
int型のmain(){
   int型のT。
  INTのN、M。
  scanf関数("%のD "& T)、
   一方(t-- ){ 
     scanf関数(" %d個の%のD "、&​​N、&M); 
     s.clear(); 
     のmemset(木、0はsizeof (木)); 
     のmemset(ルート、0はsizeof (ルート)); 
     CNT = 0 ;
      のためint型 I = 1は iが++; iがn = <; ){ 
        scanf関数(" %dを"[i])と、
        インサート(1、nは、ルート[ I- 1 ]、根[I]、[I])。
     } 
     int型 ANS。オペアンプ;
     INTの R、W、POS = 0 int型 ANS = 0 ;
     一方、(M-- ){ 
        scanf関数(" %のD "、&OP)。
        もし(OPの== 1 ){ 
           scanf関数(" %のD "、およびPOS)。
           POS = POS ^ ANS; 
           s.insert([POS])。
        } { 
          scanf関数(" %dの%のD "、&​​R&W)。
          R = R ^ = W ^
          ワットANS;
          INT NUM =クエリ(ルート[R]、根[n]は、1 、N、W)。
          もし(NUMの== 0 ){ 
            オートは = s.lower_bound(W)を。
            もし(!それ= s.end()){ 
                ANS = * それ。
                printf(" %d個の\ nを"、* それが)。
            } { 
                ANS = N + 1 
                printf(" %d個の\ n " 、ANS)。
            } 
          }  { 
            自動それは = s.lower_bound(W)を。
            もし(!それ= s.end()){ 
                ANS =分(K番目(ルート[R]、根[n]は、1、N、N-R + 1 -num)、* IT)。
            } { 
                ANS = K番目(ルート[R]、根[n]は、1、N、N-R + 1 - NUM)。
            } 
            のprintf(" %d個の\ n " 、ANS)。
          } 
        } 
     } 
  } 
  戻り 0 
}

おすすめ

転載: www.cnblogs.com/bluefly-hrbust/p/11403176.html