세그먼트 트리 (최대 간격 업데이트 + 범위)

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)) 
        (해결); 
    //} 
}

 

추천

출처www.cnblogs.com/nonames/p/12463010.html