https://nanti.jisuanke.com/t/42387
문제점 의미 N (1 <= N <= 1E5) 수가 Q (1 <= Q <= 1E5) 쿼리 시간, 모두 최초 (1). 1 MUL L, R, X 간격 [L, R은 (1 <= X는 <= 10) (X)에 의해 곱해진다. 2 쿼리 L, R 심문 간격 [L, R] 최대 인덱스 각각 소인수 분해 최대 값.
해결책 : 문제 알고 이해 한 후, 각 구간에 대한 통계의 소수이다 (2, 3, 5, 7) 수, 각 소수의 인덱스 번호의 최대 값의 최대 범위.
사 개 트리 라인의 유지 보수 (2,3,5,7) 통계는 최대 네 개의 나무 소수의 수, 쿼리 모든 나무의 최대 범위,있는 것은 답변입니다.
#INCLUDE <비트 / stdc ++. H> #INCLUDE <cstdio> #INCLUDE <CString을> #INCLUDE <cmath> #INCLUDE <알고리즘> #INCLUDE <iostream> #INCLUDE <문자열> #INCLUDE <STDIO.H> #INCLUDE <큐 > #INCLUDE <적층> #INCLUDE <지도> #INCLUDE <설정> 사용법 #include <string.h> #INCLUDE <벡터> 의 typedef 긴 긴 LL; #DEFINE INT LL #DEFINE 개조 1,000,000,007 #DEFINE GCD __gcd #DEFINE 담당자는 (ⅰ, j는, N)에 대한 (INT 난 J를 =; I <= N; I ++) 레드 #DEFINE (I, N, j)는 대 (INT I = N; I> J =; 난 -) #DEFINE ME (X, Y)가 memset (X, Y는 sizeof (X)) // LL LCM (LL A, // LL quickpow (LL의 B, A LL) {LL ANS = 1, 반면 (b) {경우 (B & 1) ANS = ANS는 *는 %의 개조, B >> = 1, A는 *는 %의 개조를 =} 반환 ANS} 와; // INT euler1 INT (X) {INT ANS는 X = (INT 내가 = 2; 나는 * I <= X; I ++) 경우 (X % I == 0) {ans- = ANS / I; 반면 (X % I == 0) X / = 1} 경우 (x> 1) = ans- ANS / X] 복귀 ANS} // CONST INT 1E7 + N = 9; INT 힘 [N], 프라임 [N], 피 [N] INT euler2 (INT N) {ME (힘, TRUE); INT LEN = 1; 렙 (I, 2, N) {경우 (힘 [I] ) {프라임 [LEN ++] = 1, 피 [I] = I - 1}에 대한 (INT J = 1; J <LEN && 프라임 [J] * I <= N; J ++) {힘 [내가 * 프라임 [J] = 0 (I % 프라임 [J] == 0) {(φ)는 [I 프라임 [J를 *] = 피 [I] * 프라임 [J] 바꿈} 만약 그렇지 {피가 [I *를 주요한 [J] = 피 [I]는 * 피 [프라임 [J]를];}}} 리턴 LEN} #DEFINE INF 0x3f3f3f3f #DEFINE PI의 ACOS (-1) #DEFINE PII 쌍 <INT는 INT> #DEFINE 인터넷 제 #DEFINE 번째 SE는 #을 L 중간 루트를 정의 LSON << 1 #DEFINE의 rson 미드 + 1, R, 루트 << #DEFINE MP make_pair #DEFINE CIN (X)는 scanf ( "%의 LLD ', X); 네임 스페이스를 사용하여 표준; CONST INT 1E7 + N = 9; CONST INT maxn 1E5 + = 9; CONST 이중 ESP = 1E-2; INT Q, N; 문자 S [20]; 구조체 노드 { INT L, R, MA, 지연; }; 구조체 {Segment_Tree 노드 트리 [maxn << 2]; 보이드 팔 굽혀 펴기 (INT 루트) { 트리 [루트] .val = 트리 [루트 >> 1] + 트리 .val [루트 >> 1 | 1] .val; 트리 [루트] .ma = 최대 (트리 [루트 << 1] .ma, 트리 [루트 << 1 | 1] .ma); } 공극 푸시 (INT 루트) { 트리 [루트 << 1] + = .ma 트리 [루트] .lazy; 트리 [루트 << 1 | 1] + = .ma 트리 [루트] .lazy; 트리 [루트 << 1] + = .lazy 트리 [루트] .lazy; 트리 [루트 << 1 | 1] + = .lazy 트리 [루트] .lazy; 트리 [루트] .lazy = 0; } 공극 빌드 (INT의 L, R INT, INT 루트) { 트리 [루트] 펜닐 = L, 트리 [루트] .R = R, 트리 [루트] .val = 0, 트리 [루트] .lazy = 0, 트리 [루트] .ma = 0; (L == R) {경우 리턴; } INT 중간 = (L +의 연구) >> 1; 빌드 (LSON); 빌드 (rson); } 공극 업데이트 (INT의 L, R INT, INT 루트 INT VA) { 경우 (트리 [루트] 펜닐> = 1 && 트리 [루트] .R <= R) { 트리 [루트] .lazy + = VA; 트리 [루트] .ma + = VA; 반환; } 경우 (트리 [루트] .lazy) 푸시 (루트); INT 중간 = (트리 [루트] 펜닐 + 트리 [루트] .R) >> 1; 경우 (L <= MID) 업데이트 (L, R, 루트 << 1, VA); 경우 (R> 중간) 업데이트 (L, R, 루트 << 1 | 1, VA); (루트) 팔 굽혀 펴기; } INT 쿼리 (INT L, R INT, INT 루트) { INT 엄마 = -INF; 경우 (트리 [루트] 펜닐> = 1 && 트리 [루트] .R <= R) { 창 트리 [루트] .ma; } 경우 (트리 [루트] .lazy) 푸시 (루트); INT 중간 = (트리 [루트] 펜닐 + 트리 [루트] .R) >> 1; 경우 (MID> = l) (MA) = 최대 (MA 쿼리 (L, R, 루트 << 1)); 경우 (R> 중간) MA 맥스 (MA 쿼리 (L, R, 루트 << 1 | 1)) =; } } PR2, PR3, PR5, PR7; () {해결 무효화 는 scanf를 ( "% LLD % LLD", N, Q); pr2.build (1 N, 1); pr3.build (1 N, 1); pr5.build (1 N, 1); pr7.build (1 N, 1); 렙 (I, 1, Q) { 는 scanf ( "% S"는, S); (S [0] == 'M'&& S [1] == 'U') 경우에 { INT의 L, R, X; scanf와 ( "% LLD % LLD % LLD ', L, R, X); 경우 (X == 2) { pr2.update (L, R, 1,1); } 다른 경우 (X == 3) { pr3.update (L, R, 1,1); } 다른 경우 (X == 4) { pr2.update (L, R, 1, 2); } 다른 경우 (X == 5) { pr5.update (L, R, 1,1); pr3.update (L, R, 1,1); } 다른 경우 (X == 7) { pr7.update (L, R, 1,1); } 다른 경우 (X == 8) { pr2.update (L, R, 1,3); } 다른 경우 (X == 9) { pr3.update (L, R, 1, 2); } 다른 경우 (X == 10) { pr2.update (L, R, 1,1); pr5.update (L, R, 1,1); } } 또 { INT L, R; INT ANS = -1; scanf와 ( "% LLD % LLD ', L, R); ANS = 최대 (ANS, pr2.query (L, R, 1)); ANS = 최대 (ANS, pr3.query (L, R, 1)); ANS = 최대 (ANS, pr5.query (L, R, 1)); ANS = 최대 (ANS, pr7.query (L, R, 1)); 의 printf ( "ANSWER의 %의 LLD \ n", ANS); } } } ) (주 서명 { // IOS :: sync_with_stdio (거짓); //cin.tie(0); cout.tie (0); // INT t; // CIN (t); // 잠시 (t -) { // 동안 (~는 scanf ( "% LLD % LF", N, a)) (해결); //} }