IKの小数点以下のお問い合わせ

リンク:https://ac.nowcoder.com/acm/contest/3979/I
出典:牛オフネットワーク

タイトル説明

 

 

アイデア:一見すると、タイトルは私が開始できない原因、私は木の線の太さを加えた木の会長に向きを考え始めるしたいのですが、修正操作があります。

その後、私は他の人がほとんどのブロックを経由して、ブログを読んで

このコードでは、各ブロックのサイズは、SQRT(N)です。

我々合計ブロックは、次に、セグメント情報を記述するために2つの配列パラメータ:L R [i]は[I]は、i番目のブロックのエンドポイントについて説明します。

そして、ソートブロック内のデータ。

更新操作のために:私たちは、左右端点全体ブロック再度点が属する横断し、次にソートの値を更新します。

  なぜ二つの別々の更新この?リフレッシュ操作が直接、更新を両方のエンドブロックをカバーするためにおそらく関係ありませんので、

  (クエリが再び変更されるまで)直接更新を引き継ぐことができ、他のブロックのLRの間、我々は怠惰なラベルされたノードに移動していること、ブロック全体をカバーすることが可能です

  ブロックサイズK変更操作が複雑である場合は、この方法ダウン、2 * K *ログ(K)である(ここで、両端点更新ブロック順序付け+)+ K(LRトラバース中間ブロック)

私たちは、半分の方法を使用して、裁判官によると、その答えを列挙:クエリのANSのうちは、以上のkであったかどうか

  実質的に同様の更新と、残りのオペレーティング。

  我々は再びそれを横断するためにあなたのブロックを周囲に終了します、更新の回答(2 * K)

  、怠惰以下の答えを決定した場合にミッドレンジ、ミッドレンジ値のトラバース、プラス私たちは、全範囲を持っています

         逆に、一致する回答の数を見つけるために全体の横断間隔で、LOWER_BOUND動作と実質的複雑さ(logk * K)logk、kがブロックの数です。

  したがって、約クエリの複雑さ(2 * K + logk * K)*ログN; K = SQRT(N)

1の#include <ビット/ STDC ++ H>
 2  の#define RINTレジスタINT
 3  の#define DEB(X)CERR <<#X << "=" <<(X)<< '\ n'は、
4  使用して 名前空間STDを、
5 typedefの長い 長いLL。
6つの 使用 PII =一対< INTINT > 7  CONST  INT MAXN = 8E4 + 5 8  整数N、M、[MAXN]。
9  int型のサイズ、bNumを、LZ [MAXN]。
10  INT L [MAXN]、R [MAXN]。
11ベクトル< int型> V [MAXN]。
12  
13インラインINT GET_ID(INT X){
 14      リターン X / サイズ。
15  }
 16  
17インラインボイド更新(int型 L、INT R、INT X){
 18      のint ID = GET_ID(L)。
19      であれば(L [ID] < L){
 20          V [ID] .clear();
21          のためにINT ; I <= R [ID] I ++ iがL [IDを] = {)
 22              [I] = 分([I]、LZ [ID])。
23             もし(I> = L && I <= r)は[I] = 分([I]、X)。
24              V [ID] .push_back([I])。
25          }
 26          ソート(V [ID])(.begin、V [ID] .END())。
27          ID ++ ;
28      } 
 29      であれば(ID> = bNumを)リターン;
30      一方、(R [ID] <= R && ID < bNumを){
 31          LZ [ID] = 分(LZ [ID]、X)。
32          ID ++ 33      } 
 34      
35      であれば(L [ID]> R || ID> = bNumを)リターン;
36      V [ID] .clear();
37     以下のためにINT iがL [IDを] =; I <= R [ID]; I ++ ){
 38          [I] = 分([I]、LZ [ID])。
39          もし(I> = L && I <= r)は[I] = 分([I]、X)。
40          V [ID] .push_back([I])。
41      }
 42      ソート(V [ID])(.begin、V [ID] .END())。
43  }
 44  
45インラインint型 CK(int型 L、INT R、int型K){
 46      のint ID = GET_ID(L)、RES = 0 47      であれば(L [ID] < {L)
 48          のためのint型私は、L =。I <=分(R [ID]、R)。I ++ ){
 49              [I] = 分([I]、LZ [ID])。
50              であれば([I] <= K)RES ++ 51          }
 52          ID ++ 53      }
 54      であれば(ID> = bNumを)戻りRES。
55      一方(R [ID] <= R && ID < bNumを){
 56          であれば(LZ [ID] <= K)RES + = R [ID] - [ID] + L 1 57の          RES + = UPPER_BOUND(V [ID])(.begin、V [ID] .END()、K) - V [ID])(.begin。
58          ID ++ ;
59      }
60      であれば(L [ID]> R || ID> = bNumを)戻りRES。
61      のためにintは ; I <=分(R [ID]、R)は、i ++ iがL [IDを] = {)
 62          [I] = 分([I]、LZ [ID])。
63          であれば([I] <= K)RES ++ 64      }
 65      リターンRES。
66  }
 67  
68インラインINTクエリ(INT L、INT R、int型K){
 69      のint L = 1、R = 1E9、ミッド。
70      一方(L <= R){
71          ミッド= L + R >> 1 72          であれば(CK(L、R、MID)> = K)、R =ミッド- 1 73           L =ミッド+ 1 74      }
 75      リターンL。
76  }
 77  
78  INT メイン(){
 79      のscanf(" %D%D "、&​​N、&M)。
80      のためにINT iが= 0、I <N; iは++)のscanf(" %dの"、+ I)。
81      サイズ= SQRT(N)、bNumを=(N - 1)/サイズ+ 1 82      のためにINT iは= 0 ; I <bNumを、iは++ ){
 83          LZ [I] = 0x3f3f3f3f 84          L [I] = I *サイズ、R [I] = I *サイズ+サイズ- 1 85          もし(I == bNumを- 1)R [I] = N - 1 86          のためにINT J = L [i]は、J <= R [i]は、J ++ )V [i]は.push_back([J])。
87          ソート(V [i]が.begin()、V [i]は.END())。
88      }
 89      ながら(M-- ){
 90          のint OP、L、R、K。
91          のscanf(" %D%D%D%D "、&​​OP、&L&R&K)。
92          l--、r--の93          であれば(OP == 1 )アップデート(L、R、K)。
94          のprintf(" %dの\ n " 、クエリ(L、R、K))。
95      }
 96 }

https://blog.csdn.net/Scar_Halo/article/details/104095690(このブログからの抜粋)

 

おすすめ

転載: www.cnblogs.com/pangbi/p/12464978.html