로스 템플릿 밸리 P3368 [2] 펜윅 나무 (트리 라인)

제목 설명

그는 컬럼의 수를 알고있는 경우, 다음과 같은 두 가지 작업을 수행해야합니다 :

1. 각 섹션 플러스 몇 가지 숫자 X

(2)의 수의 값을 구하기

입력 형식

첫 번째 라인은 N, m은 각각 열 및 동작들의 수의 총 수의 수를 나타내는 두 개의 정수를 포함한다.

수가 초기 값의 전 항목의 i 번째 열을 나타내고, 상기 제 2 라인은 공백으로 구분 N 정수를 포함한다.

다음 M 라인은 다음과 같이 2 또는 4의 정수, 그 동작을 나타내는 포함

동작 1 : 형식 : 1 XYK 의미 구간 [X, Y 각각의 수 k는 플러스

동작 2 : 형식 : 2 ×가 의미 : x 값 출력의 수가

출력 형식

출력은 라인의 정수, 전부 (2)의 연산 결과를 포함한다.

샘플 입출력

입력 # 1
5 5 
1 2 3 4 5 
1 2 4 2 
2 3 
1 1 5 -1 
1~3 5~7 
2~4
출력 # 1
(6) 
(10)

설명 / 팁

시간의 제약 : 1000MS, 128M

데이터 규모 :

데이터의 30 % : N <= 8, M <= 10

데이터의 70 % : N <= 10000, M <= 10000

데이터의 100 % : N <= 500,000, M <= 500000

샘플 설명 :

따라서, 출력 6,10이며

#INCLUDE <cstdio> 
#INCLUDE <iostream> 
#INCLUDE <cmath> 
#INCLUDE < 문자열 > 
#INCLUDE <CString을> 
#INCLUDE <알고리즘> 
#INCLUDE <큐> 
#INCLUDE <벡터> 
#INCLUDE <지도>
 사용  스페이스 성병; 

#DEFINE이 어떠냐 오래 오래
 #DEFINE의 EPS 1E-9 CONST INT INF = 0x3f3f3f3f ;
CONST INT 개조 1E9 + = 7 ; INT의 N, m, ANS, 입력 [ 500000 + 8 ];

  



구조체 노드 
{ 
    int입니다 왼쪽, 오른쪽, NUM; 
} 트리 [ 5000000 + 8. ] 

보이드 빌드 ( int로 왼쪽 int로 바로 INT의 인덱스) /// 기여 
{ 
    트리 [인덱스] .num = 0 ; 
    트리 [인덱스] .left =는 왼쪽, 
    트리 [인덱스] 됐지 = 오른쪽,
     IF는 (왼쪽 == 오른쪽) /// 노드가 리프 인 경우, 그 값은 그의 리턴 
        ;
     int로 MID = (좌측 + 우측) / 2 ; 
    빌드 (왼쪽, MID를 인덱스 *2 ) /// 왼쪽 개시 할당 부에서 
    빌드 (MID + . 1 , 오른쪽, 지수 * 2 + 1이다. ) /// 오른쪽 부분 개시 할당에서 
} 

공극 PLS ( INT의 인덱스, INT의 L, INT의 R & LT, INT K) / // 간격 K 더한 값 [L, R & LT] 
{
     IF (트리 [인덱스] .left> 트리 && L = 인덱스] 됐지 <= R & LT) /// 경우 간격 내의 객체 범위 
    { 
        트리 [인덱스 ] .num + = K;
         ; 
    } 
    IF (트리 [지수 * 2 ] 됐지> = L) /// 되도록 좌측 플러스 간격 K
        PLS (인덱스 * 2 , L, R & LT, K),
     IF (트리 [지수 * 2 + . 1 ] .left <= R & LT) /// 되도록 오른쪽 부분 플러스 K 
        PLS (지수 * 2 + . 1 , L, R & LT, K) 
} 

공극 검색 ( INT의 인덱스, INT DIS) /// 그 지점을 발견하고, 그의 기록 값 
{ 
    ANS + 트리 = 인덱스] .num; /// 기록 동작 후 증가 / 감소 값 
    IF ( 트리 [인덱스] == .left 트리 [인덱스] 됐지)
         ;
     IF (DIS <= 트리 [지수 * 2 ] 됐지) /// 이 번호 인덱스 포인트 오른쪽 아들 미만이면 왼쪽으로 찾을
        검색 (인덱스 * 2 , DIS)
     IF (DIS> = 트리 [지수 * 2 + 1이다. ] .left) /// 이 숫자들은 왼쪽 아들 지점의 지수보다 큰 경우에 적합한 모양을 
        검색 (지수 * 2 + . (1) , DIS는) 
} 

int로 요점 () 
{ 
    는 scanf ( " %의 D %의의 D " , 및 N-, 및 , m) 
    (빌드 1. , N-, 1. ) /// . 초기 시작의 각각에 할당 된 값 1 
    에 대해 ( INT I = 1. ; I <= N-; I ++ ) 
        는 scanf ( " %의 D " ,입력 [I]);
    위한 ( int로 난 = 1 ; i가 <m = 내가 ++ ) 
    { 
        int로 단계; 
        scanf와 ( " 가 % d " , & A );
        경우 (a == 1 ) 
        { 
            INT의 X, Y, Z; 
            scanf와 ( " % D % D % D ' , X, Y, Z); 
            PLS ( 1 , X, Y, Z); 
        } 
        다른  경우 (A == 2 ) 
        { 
            ANS = 0 ;
            INTX] 
            는 scanf ( " %의 D ' , X), 
            검색 ( . 1 , X) /// 이 X 위치를 찾아 루트부터 
            의 printf ( " % D의 \의 N-를 " , ANS + INPUT [X]); 
        } 
    } 
    리턴  0 ; 
}

 

추천

출처www.cnblogs.com/RootVount/p/11278631.html