ツリーを変更するには

ツリーを変更するにはC.
テストあたりの時間制限
2秒
テストごとのメモリ制限
256メガバイト
入力
標準入力
出力
標準出力

あなたは、からなる根ざしツリー与えられた  n個  の番号が頂点  1に  n個をツリーのルートは、頂点番号である  1。

最初に、全ての頂点が多数含まれて  来る次に0を  q個の  クエリを、各クエリは、2つのタイプのいずれかになります。

  • クエリの形式:  、V  、X  、Kクエリに応答して、あなたは頂点に番号を追加する必要がある  のV  数の  X ; 数字に  頂点の子孫  V  距離で  1、追加  Xは  -  kはように、頂点の子孫で書かれた番号に  V  距離で  私は、あなたが追加する必要がある  のxを  - (IK)。2つの頂点間の距離は、これらの頂点間の最短経路のエッジの数です。
  • クエリの形式:  、V問い合わせへの返信では、頂点に書かれた番号印刷する必要があります  Vの  剰余  十億七  (10 9 + 7)。

入力で与えられたクエリを処理します。

入力

最初の行は、整数含ま  N  (1≤  nは  3・10≤ ツリーの頂点の数- 5)。2行目は含ま  nは  1つの整数-  P 2、  P 3、...  、P N1つの≤  P iは  <  I)、  P iは  頂点の親である頂点の数であり、  I  ツリーです。

3行目は整数含ま  Qを  (1つの≤  Q  ≤3・10 5) -クエリの数。次  のq  行は、クエリ、1行に1つずつ含まれています。行の最初の数である  タイプこれは、クエリの種類を表します。もし  タイプ  = 1の場合、次の後続のスペースで区切られた整数  V、  X、  K  (1≤  V  ≤  nは、  0≤  X  <10 9 + 7;  0≤  K  <10 9 + 7)。場合  種類  = 2は、次の整数以下の  Vを  (1つの≤  V ≤の  N) -あなたは数の値を見つける必要が頂点。

出力

単一ライン上の第二のタイプのプリントの各クエリの数は、クエリから頂点に書き込まれます。数モジュロ印刷  十億七  (10 9 + 7)。

入力
コピー
3 
1 1
3
1 1 2 1
2 1
2 2
出力
コピー
2 
1
注意

:あなたはここに根付いた木について読むことができます  http://en.wikipedia.org/wiki/Tree_(graph_theoryを)。

#pragma GCC最適化(2)

の#include <ビット/ STDC ++ H>
 に#define lowbit(x)は、x&( - X)
 使用 名前空間STDを、
CONSTの INT MAXN = 1E6 + 108 
typedefの長い 長いLL。
CONST LL MOD = 1E9 + 7 

INTのN、Q。
INT FA [MAXN]、DFN [MAXN]、SIZ [MAXN]、DEP [MAXN]。
ベクター < INT > E [MAXN]。

インラインINT DFS(INT CUR){
     静的 INT TOT = 0 
    DFN [CUR] = ++TOT;
    ため(登録をint i = 0 ; iは、Eを<CUR] .size(); ++ I){
         int型 =にE [CUR] [I]。
        SIZ [CUR] + = DFS(へ)。
    } 
    // のprintf( "デバッグDFN [%のD] =%Dを\ n"、CUR、DFN [CUR])。
    戻る ++ SIZ [CUR]。
} 

構造体BIT { 
    [MAXN] O LL。
    インラインボイドのinit(){ 
        memsetの(O、0はsizeof (O))。
    } 
    インラインボイド更新(int型のPOS、LLのヴァル){
         一方(POS <= N){
            O [POS] =([POS] +ヴァルO)%MOD。
            POS + = lowbit(POS)。
        } 
    } 

    インラインLLクエリ(int型POS){ 
        LL RES = 0 一方(POS){ 
            RESの =(RES + O [POS])%MOD。
            POS - = lowbit(POS)。
        } 
        戻り RES%MOD。
    } 

} atom1、atom2の。



INT メイン(){ 
#ifndefのONLINE_JUDGE 
    freopenは(" 1.TXT "" R "、STDIN)。
#endifの
    scanf関数(" %のD "、&N)
    (登録をint i = 2 ; iが<= N; ++ I){ 
        scanf関数(" %のD "、&FA [I])。
        。E [FA [I] emplace_back(I)。
        DEP [I] = DEP [FA [I] + 1 
    } 
    atom1.init()。
    atom2.init(); 
    DFS(1 )。
    scanf関数(" %のD "、&Q)。
    int型のタイプ、V、X; 
    LL K; 
    一方、(q-- ){
        scanf関数(" %のD "、&タイプ);
        もし(タイプ== 1 ){ 
            scanf関数(" %D%D%LLD "、&​​V、およびX&K)。
            atom1.update(DFN [V]、X + DEP [V] * k個の%のMOD)。
            atom1.update(DFN [V] + SIZ [V]、mod-(X + DEP [V] * k個の%のMOD)%のMOD)。
            atom2.update([V]、K DFN)。
            ([V] DFN atom2.update + SIZ [V]、(MOD-K%MOD)%のMOD)。
        } 
        { 
            scanf関数(" %のD "、&V)。
            printf("(atom1.query([V])%MOD-DEP DFN [V] * atom2.query([V])%のMOD + MOD DFN)%のMOD); 
        } 
    } 
    戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/czy-power/p/11457057.html