月にhdu4348(セグメントツリーは永続的であってもよいです)

トピックへのリンク:http://acm.hdu.edu.cn/showproblem.php?pid=4348

タイトル効果:指定された数を含む配列N、以下の4つの操作

1.CのLRD:区間[L、R]プラス数Dの表現、及び時間プラス1

2.QのLR:現在の時間間隔[L、R]を照会、及び

3.HのLRT:呼掛け時間間隔T [L、R]、及び

4.BのT:Tバックまでの時間

サンプル入力

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
2 4
0 0
C 1 1 1
C 2 2 -1
Q 1 2
H 1 2 1
サンプル出力
4
55
9
15

0
1

 

問題解決のアイデア:セグメントツリーを求めているし、使用している場合、すべての偉大なパスの下で、そしてスペースが消費されますので、あなたがメモリをバーストする可能性がある、間隔で怠惰なパスをマークすることはできません、我々は直接、怠惰の電流範囲を尋ねたことができたときに場合パラメータのパスで標識され、そして、必要なセクションを見つけ、直接蓄積マーカーに上から下怠惰にこの間隔プラスオリジナル間隔との長さを乗算します。

コード:

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
typedefの長い 長いLL。
const  int型 MAXN = 1E5 + 7 構造体ノード{
     int型のL、R。
    LL怠惰、合計。
}ツリー[MAXN * 30 ]。
INTのN、M、T、CNT、ルート[MAXN]。
ボイド押し上げ(INT RT、INT L、INT R){ 
    ツリー[RT] .SUM =ツリー[ツリー[RT] .L] .SUM +ツリー[ツリー[RT] .R] .SUM +ツリー[RT] .lazyを*(R-L + 1 )。
} 
無効ビルド(INT&RT、int型L、INT R){ 
    RT = ++ CNT。
    ツリー[RT] .lazy = 0 もし(L == R){ 
        scanf関数(" %のLLD "、&ツリー[RT] .SUM)。
        返します
    } 
    INT半ば=(L + R)/ 2 
    (ツリー[RT] .L、L、中間)を構築します。
    ビルド(ツリー[RT] .R、中間 + 1 、R)。
    押し上げ(RT、L、R)。
} 
ボイド更新(INT&今、int型プリ、int型の L、int型の R、INTヴァル、int型の L、INT R){  = ++ CNT、ツリー[今] = ツリー[事前]。
    もし(L <= 1 && R> = R){ 
        ツリー[今] .SUM + = 1LL *(R-L + 1)* ヴァル。
        ツリー[今] .lazy + = ヴァル。
        返します
    } 
    INT半ば=(L + R)/ 2 もし(L <= MID)更新(ツリー[今] .L、ツリー[事前] .L、L、R、ヴァル、L、MID)。
    もし(R> MID)更新(ツリー[今] .R、ツリー[事前] .R、L、R、ヴァル、中間+ 1 、R)。
    押し上げ(ここで、L、R)。
} 
LLクエリ(int型になりました、int型の L、INT R、int型怠惰、int型の L、int型R){
     場合(L <= 1 && R> = R){
         戻りツリー[今] .SUM + 1LL *(R-L + 1)* 怠惰。
    } 
    INT半ば=(L + R)/ 2LLのRES = 0 
    怠惰 + = ツリー[今] .lazy。
    もし(MID> = L)RES + = クエリ(ツリー[今] .L、L、R、怠惰、L、MID)。
    もし(MID <R)RES + =クエリ(ツリー[今] .R、L、R、怠惰、中間+ 1 、R)。
    リターンのres; 
} 
int型のmain(){
     チャー OP [ 10 ]。
    scanf関数(" %d個の%のD "、&​​N、&M)。
    ビルド(ルート[ 0 ]、1 、N)
    int型のL、R、ヴァル、T。
    T = 0 一方、(M-- ){ 
        scanf関数(" %sの" 、OP)。
        もし(OP [ 0 ] == ' C ' ){ 
            scanf関数(" %D%D%D "、&​​L&R&ヴァル)。
            トン ++ ; 
            アップデート(ルート[T]、根[T - 1 ]、L、R、ヴァル、1、N)。
        } そう であれば(OP [ 0 ] == ' Q ' ){ 
            scanf関数(" %d個の%のD "、&​​L&R)。
            printf(" %LLDする\ n "、クエリ(ルート[T]、L、R、01 、N))。
        } そう であれば(OPが[ 0 ] == ' H ' ){ 
            scanf関数(" %D%D%D "、&​​L&R&T)。
            printf(" %LLDする\ n "、クエリ(ルート[T]、L、1 、N))。
        } そう であれば(OP [ 0 ] == ' B ' ){ 
            scanf関数(" %のD "、&T)。
        } 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/zjl192628928/p/11230113.html
おすすめ