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 ; }