E - アップルツリー(フェンウィックツリー+ DFS順)

リンゴの木はカカーの家の外にあります。毎年秋には、りんごの多くは木に成長します。カカは非常に多くのリンゴを好きなので、彼は慎重に大きなリンゴの木を育ててきました。

ツリーはありNの枝で接続されているフォークを。カカ番号に1によるフォークNと根が常に1りんごによって番号が付けられてはフォークの上に成長すると2個のりんごは同じフォーク上に成長しません。カカはリンゴの木の生産能力の彼の研究のために、サブツリーにありますどのように多くのリンゴ知りたいです。

トラブルは、新しいリンゴが空のフォークにいくつかの時間を育てることとカカーは彼のデザートに木からリンゴを選ぶかもしれないということです。あなたはカカーを助けることができますか?

入力

最初の行は、整数含まNNツリー内のフォークの数であり、100,000以下)、。
次のN - 1行それぞれは、2つの整数含むU及びVフォーク意味し、U及びフォークVが分岐によって接続されています。
次の行は、整数含まMM ≤100,000)。
次のM個の行それぞれのいずれかであるメッセージ含有
CのXフォークアップルの存在を意味し、」Xを変更されました。フォーク上のリンゴがある場合、すなわち、その後、カカはそれを選びます。そうでない場合は、新たなリンゴが空のフォークに成長してきました。
又は
QのXフォーク上記サブツリー内のリンゴの数の問い合わせを意味し、」XをフォークX上のりんごを含むが、(存在する場合)
ツリーは冒頭にりんごのいっぱいであることに注意してください

出力
すべてのお問い合わせについては、出力行あたりの対応の答え。
サンプル入力
3 
1 2 
1 3 
3 
Q 1つの
C 2 
Q 1
サンプル出力
3 
2 ソリューション1.変更ノードの値(0〜1の変換):タイトルは、2つの作用を有します。2.ノードとそのすべての子ノードの値と所有権を確認して下さい。私たちは、DFSの各元ノードに対して、ノード数を記録し、1から再番号付けすることができます起動し、[i]と最も多くのエンドの子ノードは、[i]は、我々は、ノードへの権利とそのバイト点のすべてを照会とき合計は、フェンウィックツリーを見つけるための方法を使用することができます:SUM [エンド[I]] - SUM([スタート]、[I] -1)。



#include <iostreamの> 
する#include <CStringの> 
する#include <ベクトル> 
の#include < ストリング > 
する#include <stdio.hの>
 使用して 名前空間STD。
typedefの長い 長いLL。
INT lowbit(INT X){ 戻り X& - X;}
 のconst  int型 MAXN = 100010 整数nは、[MAXN] C。
ボイド更新(int型のx、int型V)
{ 
    ためint型 I = xをiが+ =; iが<= N lowbit(I))
        C [i]は+ = V; 
} 
int型の和(INT X)
{ 
    int型 ANS = 0 int型 ; I> = I = xを1、I- = lowbit(I))
        ANS + = C [i]は、
    戻るANSを。
} 
構造体ノード
{ 
    int型V、次。
} E [MAXN * 2 ]。
int型 CNT = 1 ;
int型のヘッド[MAXN]。
ボイド追加(INT U、INT V){ 
    E [CNT] .V = V。 
    E [CNT] .next = 頭部[U]。
    ヘッド[U] = CNT ++ 
} 
INT TOT = 0 INT スタート[MAXN]、[MAXN] END;
int型VISS [MAXN]。
ボイド DFS(INT X)
{ 
    スタート[X] = ++ TOT。
    以下のためにint型 - ;!I = I =ヘッド[X] 1 ; I = {E [I] .next)
        DFSの(e [i]の.V)。
    } 
    エンド[X] = TOTを、
} 
int型のmain()
{ 
    memsetの(頭、 - 1はsizeof (ヘッド))。
    scanf関数(" %のD "、&N)
    以下のためにint型 I = 1 ; I <= N- 1、I ++ ){
         int型Uを、V。
        scanf関数(" %d個の%d個"、&​​U&V); 
        (V、U)を追加します。
    } 
    DFS(1 )。
    memset(VISS、1はsizeof (VISS))。
    以下のためにint型 i = 1 ; iが<= N; iが++)C [I] = lowbit(I)。
    int型Q; 
    scanf関数(" %d個"、&Q);
    一方(q--){
         チャー S [ 10 ]。
        int型のx; 
        scanf関数(" %sの%は、D "、S、およびX)
        もし(S [ 0 ] == ' Q ' ){ 
            のprintf(" %Dを\ n "、和(完[X]) -和(スタート[X] - 1 ))。
        } 
        {
             場合(!{VISS [X])
                VISS [X] = 1 
                更新(スタート[x]は、1 )。
            }
             {
                VISS [X] = 0 
                更新(スタート[X]、 - 1 )。
            } 
        } 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/cherish-lin/p/10960889.html