セグメントツリー(更新間隔、間隔の合計)

1082セグメントツリー演習3

タイトル説明説明

あなたの数Nを付け、2つの動作モードがあります。


1:すべてのセクションの数[a、b]は増加するX


2:番号呼び掛け区間[A、B]と。

説明の入力入力説明を

正の整数nの最初の行、N次ラインnの整数、

 

再び正の整数Q、各行は操作の数を表し、

 

最初の数は3つの正の整数が続き、1であれば、

 

それが2である場合、間隔数Xで[B]各増加を示します

 

図2は、操作呼び掛け区間[a、b]は、どれだけを表します。

 

パスカル選手はreadln読み取りを使用していません

出力の説明出力説明

クエリの出力線に各回答のため

サンプル入力サンプル入力

3

1

2

3

2

1 2 3 2

2 2 3

サンプル出力の出力例

9

データ範囲とプロンプトデータサイズ&ヒント

データ範囲

1 <= N <= 200000

1 <= Q <= 200000

WA需要インターバルとバーストINTので、最初のサーブ

#include <iostreamの> 
する#include <iostreamの> 
する#include <cstdioを> 
する#include < ストリング > 
の#include <CStringの> 
する#include <アルゴリズム> 
する#include <stdio.hに> 
する#include < 文字列・H>
 に#define担当者(I、 n)がため(INT i = 0; iが(N <); iは++)
 使用 名前空間STDを、
const  int型 N = 1100009 ;
長い 長い ANS = 0、フラグ= 1 INT [ 1000009 ]、[B 1000009 ]。

構造体ノード{
     長い   L、R、ヴァル、lazy_tag。
}ツリー[N * 4 ]。

ボイドビルド(int型 L、int型の R、int型のルート)
{ 
    ツリー[ルート] .L = L、木[ルート] .R = R。
    ツリー[ルート] .lazy_tag = 0 もし(L == R)
    { 
        scanf関数(" %のD "、&ツリー[ルート] .val)。
        返します
    } 
    INT半ば=(L + R)>> 1  
    ビルド(L、中間、根 * 2 ); 
    (MIDビルド + 。1、R&LT、ルート* 2 + 。1 ); 
    ツリー[ルート] .val =ツリー[ルート* 2 ] +ツリー.val [ルート* 2 + 1 ] .val; 
} 

ボイド(プッシュダウンINT ルート)
{ 
    ツリー[ルート * 2 ] + = .lazy_tagツリー[ルート] .lazy_tag; // ノートマーク蓄積 
    ツリー[ルート* 2 + 1 ] + = .lazy_tag ツリー[ルート]。 lazy_tag;
     // 子ノードの値が更新 
    ツリーを[ルート* 2 ] + = .val(ツリー[ルート* 2 ] .R -ツリー[ルート* 2 ] + .L 1。)*ツリー[ルート] .lazy_tag; // 親ノードの子乗算の遅延間隔長 
    ツリー[ルート* 2 + 1 ] + = .val(ツリー[ルート* 2 + 1 ] .R -ツリー[ルート* 2 + 1 ] .L + 1)* ツリー[ルート] .lazy_tag; 
    ツリー[ルート] .lazy_tag = 0 ; // 親ノードのフラグを解除
}
 ボイド更新(int型 L、INT R&LT、INT addval、INT ルート)
{ 
    IF(ツリー[ルート] .L> = L &&ツリー[ルート] .R <= R&LT)
    { 
        ツリー[ルート] .lazy_tag + = addval; // 前にそこに蓄積されてもよい、このフラグは、添加剤であることに留意されたい 
        ツリー[ルート] .val = +(ツリー[ルート] .R -ツリー[ルート] .L + 1)* addval; // 各マークするために蓄積されてしまうため、これは、addvalを乗じて
        戻る; 
    } 
    IF (ツリー[ルート] .lazy_tag)
        プッシュダウン(ルート); 
    int型 MID =(ツリー[ルート] .L +ツリー[ルート] .Rを)>> 1。;
     IF(L <= MID)
        更新(L、R&LT、addval、ルート * 2 );
     IF(R&LT > MID)
        更新(L、R&LT、addval、根* 2 + 1 )。

    ツリー[ルート] .val =ツリー[ルート* 2 ] .val +ツリー[ルート* 2 + 1 ] .val。
} 

ボイド   クエリ(int型 L、int型の R、int型のルート)
{ 
    場合(ツリー[ルート] .L> = L &&ツリー[ルート] .R <= R)
    { 
        ANS + = ツリー[ルート] .val。
        返します
    } 
    もし(ツリー[ルート] .lazy_tag)
        プッシュダウン(ルート)。
    INT半ば=(ツリー[ルート] .L +ツリー[ルート] .R)>> 1 もし(L <=MID)
        クエリ(L、R、根 * 2 )。
    もし(R> MID)
        クエリ(L、R、根 * 2 + 1 )。

    ツリー[ルート] .val =ツリー[ルート* 2 ] .val +ツリー[ルート* 2 + 1 ] .val。
} 



int型のmain()
{ 
    int型N;
    一方、(〜のscanf(" %d個"、&N))
    { 
        構築(1、N 1 )。
        int型Q; 
        scanf関数(" %d個"、&Q)。
        以下のためにint型 i = 0 ; iは、Q <I ++の
        { 
            int型のFと、
            scanf関数(" %のD "、&F)。
            もし(== F 1 
            { 
                int型のX、Y、addval。
                scanf関数(" %D%D%D "、およびX&Y、&addval)。
                アップデート(X、Y、addval、1 )。
            } 
            
            { 
                int型X、Y。
                scanf関数("%D%D 、およびX&Y)、
                クエリ(X、Y、1 ); 
                COUT << ANS << ENDL; 
                ANS = 0 ; 
            } 
        } 
    } 

    戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/nonames/p/11260015.html