質問の意味:3つの動作があります。
処置1:私は右の値が0である、新しい子ノードを成長ノードを表す、最大数は、現在の番号+1である(現在の動作が1いくつかの最初のものであるとしても理解することができる、数が新しいノードの数です)。
操作2:huahuaすべてのノードのサブツリー・ノードのiが(すなわち、それは、その子孫のすべてのノード)の重み合計ライン上のタスクを実行表します。
お問い合わせ3:この時点ではノードi与えhuahua必要性の重み。
ソリューション:
ツリー全体をオフライン
重量値が直接サブツリー全体でプラス体重片は、後で新しい空の重量小数点値を追加することができたときにまずこのDFSのツリーは、サブツリーのノードは、連続しています。
操作が1であるときは、右の値は、この点をクリアします
2.動作し、全てこのノードのサブツリーのノードの重みプラスI
図3に示すように、操作、クエリノードiの重量
DFN [I]配列のツリー上の点iの位置を記録し、SZ [i]は、ノードiのサブツリーの大きさであります
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型の M = 4E5 + 10 。 int型のCNT、TOT、N。 構造体のエッジ{ INT に、次。 }エッジ[M * 2 ]。 構造体ノード{ int型OPT、POS、X。 } [M]。 INTのDFN [M]、SZ [M]、ヘッド[M]、ビット[M]。 ボイド add_egde(INT U、INT V){ // のprintf( "U%DV%D \ n"は、U、V)。 エッジ[++ TOT] .next = 頭部[U]。 エッジ【TOT] .TO = V。 ヘッド[U]= TOT。 } int型の DFS(INT U、INT FA){ DFN [U] = ++ CNT。 SZ [U] = 1 。 用(INT ; iは= Iがヘッド= [U] {エッジ[I] .next)を int型、V = エッジ[I] .TO。 もし(V == FA)は継続。 SZ [U] + = DFS(V、U)。 } 戻りSZ [U]。 } ボイド更新(INT I、int型X){ ながら(I <= N + 1){ ビット[I] + = X。 I + = I&( - I)。 } } ボイド追加(int型 L、INT R、INT ヴァル){ 更新(L、ヴァル)。 更新(R + 1、 - ヴァル)。 } INTクエリ(INT I){ int型 ANS = 0 。 一方、(I){ ANS + = ビット[I]; I - = I&( - I)。 } 戻りANS。 } int型のmain(){ int型メートル; scanf関数(" %のD "、&M)。 以下のために(INT iが= 1 ; I <= M; I ++ ){ scanf関数(" %D%D "、および[I] .OPT、&[I] .POS)。 もし([I] .OPT == 1)add_egde([I] .POS、++ n)は、[I] .POS = N。 もし([I] .OPT == 2)のscanf(" %dの"、および[I] .X)。 } DFS(0、 - 1 )。 以下のための(int型 I = 1; I <= M。I ++ ){ 場合([i]が.OPT == 1 ){ int型、U = A [i]の.POS。 INTヴァル= クエリ(DFN [U])。 追加(DFN [U]、DFN [U]、 - ヴァル)。 } 他の 場合([i]が.OPT == 2 ){ int型、U = A [i]の.POS。 INTヴァル= A [i]の.X。 追加(DFN [U]、DFN [U] + SZ [U] - 1 、ヴァル)。 } 他のprintf(" %dの\ n " 、クエリ(DFN [[I] .POS]))。 } リターン 0 ; }