誰がほとんどキャンディーズPOJを取得します - ?2886(抗ホルモンのセグメントツリーの単一ポイント更新間隔+ +クエリ数)

予備知識:抗分析プライムの数

アイデア:ソリューションで抗素数後は、セグメントツリーの事です。

除去することができ、誰が解消されていない私たちは、木のメンテナンスの位置でラインを出していなかった人の位置を排除しました。

私たちは[1、n]の範囲のように表現皆を置くことができ、人権が解消されていない1で、その後、メンテナンス間隔と木のラインで、それを排除することはできませんが、人の分布を知って、ツリー[ルート] .VALUE合計数です。ツリーラインのバイナリ性質上ので、x番目の位置にある人のうちなら、我々は範囲や位置の人の位置を取得するには、X、この位置への権利は、値0を更新し、ツリーラインを更新を見つけることができ、それこれは、人々が排除された表現できる、総数はマイナス1である、それはゲームに残っているどのように多くの人々を示すことができます。

これは、人の位置から外れていると仮定するとINX、位置の男の次のうちで彼の左(および右)A-番目、私たちは、MOD = A%(残数)、その後、我々は数の左INX(L)と右を得ることができますすることができます(R)は、その後、個人やMOD符号に基づいて次の位置を決定します。

  1の#include <iostreamの>
   2の#include <cmath>
   3の#include <cstdioを>
   4  
  5  の#define LL長いロング
   6  
  7  使って 名前空間STDを、
  8  
  9  CONST  整数 N = 5E5 + 10 10  構造体情報{
 11      チャー名[ 20 ]。
12      int型のターン。
13  } P [N]。
14  構造体ノード{
 15      のint L、R、値。
16      INT中間(){ リターン(L + R)>> 1 }
 17 }ツリー[N << 2 ]。
18  int型C [N]。
19  INT N、S、SS、INX。
20  INT PR [] = { 2357111317192329 }。
21  INT マックス、NUM;
22の 
23  空隙 DFS(int型 INX、INT V、int型の CNT、INT PW){
 24     以下のためにINT iが= 1 ; I <= PW; ++ I){
 25          であれば((LL)V * PR [INX]> (LL)N){
 26              であれば(最大<CNT * I){
 27                  マックス= CNT * I;
28                  NUM = V;
29                  
30              } そう であれば(CNT * I ==最大)NUM = 分(NUM、V)。
31              ブレーク;
32          }
 33          他の DFS(INX + 1、V * = PR [INX]、CNT *(I + 1 )、I);
34  
35      }
36  }
 37  
38  // 反素数模板
39  空隙AntPrime(){
 40      マックス= 1 41の      DFS(01130 )。   
42  }
 43  
44  空隙 build_tree(int型 RT、INT L、INT R){
 45      ツリー[RT] .L = L。ツリー[RT] .R = R。
46      であれば(L == R){
 47          であれば(L == S)INX = RT。
48         ツリー[RT] .VALUE = 1 49          リターン;
50      }
 51      int型のミッド= ツリー[RT] .MID()。
52      INT LSON = RT << 1 53      int型 rson = RT << 1 | 1 ;
54      build_tree(LSON、L、MID)。
55      build_tree(rson、ミッド+ 1 、R)。
56      ツリー[RT] .VALUE =ツリー[LSON] .VALUE + ツリー[rson] .VALUE。
57  }
 58  
59  空隙更新(INT X){
 60      、一方(X =!1。){
 61である          - ツリー[X] .Valueの、
 62は          X = >> 1 ;
 63れる     }
 64  }
 65  
66  空隙検索(INTの TOT、INT RT){
 67      // 位置を見つける
68      IF(ツリー[ RT] .L == ツリー[RT] .R){
 69          SS =ツリー[RT] .L; // 元の待機位置
70          INX = RT; // 更新を容易にするために、セグメントツリーの位置、
71は         リターン;
 72      }
 73 IS      int型 LSON = RT <<。1 ;
 74      int型 RT = << rson 。1 | 。1 ;
 75      IF(木[LSON] .Valueの> = TOT)検索(TOT、LSON);
 76      他の検索(TOT - ツリー[LSON] .Valueの、rson);
 77  }
 78  
79  ボイド)(解決{
 80      ながら(〜scanfの(" %のD%のD "、およびN-&S)){
 81          (build_tree 。11 、N-);
 82          AntPrime(); // GETエマープと程度の数の数
83          のためにint型= I 1、I <= N; ++ I){
 84              scanfの(" %S%D "、P [I] .nameの、&P [I] .turn);
 85          }
 86          INT CNT = 0 ;
 87          INT = REMAIN N-;
 88          // S人のキュー位置うち
 89          // SSは、人の元の待機位置
90          SS = S;
 91である         一方で(!++ CNT = NUM){
 92              更新(INX); // セグメントツリーを更新する
93              int型回し= ABS((ダブル)P [SS] .turn)。 
94              ターン%=(まま- 1 )。
95              もしターン=のまま- (ターン!)1 96              もし(P [SS] .turn> 0 ){ 
 97                  INT R =まま- S。
98                  であれば(R> =ターン)S = S +ターン- 1 99個の                 他の S =ターン- R。
100              } そうでなければ{
 101                  のintリットル= S - 1 102                  場合(L> =ターン)S = L -ターン+ 1 103の                 他の S =(残っている- 1) - (ターン- L)+ 1 104              }
 105              // COUT << << SS << ENDL "位置です"。
106              // coutの<< << P [SS] .nameの<<てendl "人を飛び出しました"。
107              検索(s、1 )。
108              - 残ります。
109          }
 110          のprintf(" %sの%D \ n " 、P [SS] .nameの、最大)。
111      }    
 112  }
 113  
114  INT のmain(){
 115  
116      (解きます)。
 
      ;
119 }

 

おすすめ

転載: www.cnblogs.com/SSummerZzz/p/12569041.html