누가 가장 캔디 POJ를 가져옵니다 - 2886 (세그먼트 트리 단일 지점 업데이트 간격 방지 호르몬의 + + 쿼리 수)

사전 지식 : 안티 - 분석 소수의 수

아이디어 : 안티 - 소수 후 솔루션은 세그먼트 트리 것입니다 함께.

제거 할 수 있고, 사람이 제거되지 않은 우리는 트리 유지 보수의 위치와 라인 밖으로되지 않은 사람의 위치를 ​​제거.

우리는 아는 사람들의 분포를 A와 표현 모두 넣어 [1, n]은 범위, 인권이 제거되지 않은 한 후 유지 보수 간격 및 트리 라인으로, 그것을 제거 할 수는 없습니다, 트리 [루트] .value 총 수입니다. 는 x 번째 위치에있는 사람들 중, 우리가 범위를 찾을 수와 위치가 사람의 위치를 ​​얻기 위해 X 경우 트리 라인의 진 본성,이 위치에 대한 권리는 0 값을 갱신하고 있기 때문에 다음, 그것을 트리 라인을 업데이트 이 사람들이 탈락했다 나타낼 수, 총 수는 마이너스 1, 그것은 게임에 남아 있습니다 얼마나 많은 사람들이 나타낼 수 있습니다.

이 사람의 어긋난 것을 가정하면 INX,있는 사람의 다음 밖으로 그의 왼쪽 (오른쪽) A-일, 우리는 모드 = A % (나머지 번호), 우리는 숫자 왼쪽 INX (L)과 오른쪽을 얻을 수 있습니다 (R)은 다음과 개별적인 개조 부호에 기초하여 다음의 위치를 ​​결정한다.

  1 #INCLUDE <iostream>
   2 #INCLUDE <cmath>
   3 #INCLUDE <cstdio>
   4  
  5  #DEFINE LL 긴 길이
   6  
  7  이용한  스페이스 성병;
  8  
  9  CONST의  INT N = 5e5 + (10) ;
10  구조체 정보 {
 11       이름 [ 20 ];
12      INT 차례;
13  } P [N];
14  구조체 노드 {
 15      INT의 L, R, 값;
16      INT 중반 () { 반환(L +의 연구) >> 1 ; }
 17 } 트리 [N << 2 ];
18  INT의 C [N];
19  INT N, S, SS, INX;
20  INT PR [] = { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 };
21  INT 맥스 NUM;
22  
23  공극 DFS ( INT의 INX, INT V, INT의 CNT, INT PW) {
 24     위한 ( INT 난 = 1 ; I <= PW; ++ I) {
 25 일          경우 ((LL) V * PR [INX]> (LL) N) {
 26 일              경우 (최대 <CNT * I) {
 27                  최대 = CNT * 난;
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 ( 0 , 1 , 1 , 30 );   
42  }
 43  
44  공극 build_tree ( INT의 RT, INT L, INT R) {
 45      트리 [RT] 펜닐 = 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) 인      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를 ( 1. , 1. , N-)를,
 82          AntPrime을 (); // GET emirp하고 약 수의 수 
83           ( INT= I . 1 ; I <= N-; ++ I) {
 84              는 scanf ( " % S % D " , P [I] .name과, P [I] 프로젝 터);
 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] 프로젝 터); 
94              턴 (%) = (남아 - 1 );
95              의 경우 회전 = 남아 - (차례!) 1 ;
96              의 경우 (p [SS] 프로젝 터> 0 ) { 
 97                  INT의 R의 남아 = - S;
98                  의 경우 (R> = 턴) S = S + 턴 - 1 ;
99                  다른 S = 턴 - R;
100              } {
 101                  INT의 L 개의 S = - 1 ;
102                  경우 (L> = 턴) S = 1 - 턴 + 1 ;
(103 개)                  다른 사람 들 = (남아 - 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