地方選挙D2T3テストボードそれは本当にまれです。。。。~~~
この問題は、各クエリ操作ごとに、uからvへのパスを維持するために、操作を追加し、Uにサブツリーのルートを依頼するための裸の鎖分割ツリーです。チェーンは、私が見ることができる木分割されない場合は、期間のブログへの、コード内の細部を詳細に行くことはありません-
リファレンスコードは以下のとおりであります:
#include <iostreamの> する#include <cstdioを> の#define N 400005 の#define M 800005 の#define LC K * 2 の#defineのRC K * 2 + 1台 の#define半ば(L + R)/ 2 長の長いの#define INT 名前空間stdを使用して; 構造体ノード { int型のL、R、W、タグ。 }ツリー[4 *のN]。 N INT、M、R、P、X、Y、Z。 int型V [M]、ヘッド[M]、NXT [M]、CNT。 INT DEP [N]、FA [N]、息子[N]、サイズ[N]、トップ[N]、SEG [N]、ID。 文字Q; 読み取りINT() { int型のx = 0、F = 1; CHAR CH = GETCHAR()。 一方、(CH < '0' || CH> '9'){IF(CH == ' - ')は、f = -1; CH = GETCHAR();} 一方(CH> = '0' && CH <= '9 「){X = X * 10 + CH-48、CH = GETCHAR();} 戻りのx * Fを、 V [++ CNT]はBを=。 NXT [CNT] =ヘッド[A]。 [A] = CNTヘッド。 } ボイドDFS1(INTノード、父INT) { DEP [ノード] = DEP [父] +1。 FA [ノード] =父。 サイズ[ノード] = 1。 int型maxson = -1; 用(INT I =ヘッド[ノード]; I; I = NXT [I]) { int型行く= Vの[I]。 (==父親を行く)続行。 DFS1(行く、ノード)。 サイズ[ノード] + =サイズ[移動]。 IF(サイズ[移動]> maxson)maxson =サイズ、[移動]息子[ノード] =行きます。 } } ボイドDFS2(INTノード、int型topfather) { SEG [ノード] = ++ ID。 トップ[ノード] = topfather。 (!息子[ノード])であればリターン。 DFS2(息子[ノード]、topfather)。 用(INT I =ヘッド[ノード]; I; I = NXT [I]) { int型行く= Vの[I]。 場合(行く== FA行く|| [ノード] ==息子[ノード])続けます。 DFS2(行く、行きます)。 } } ボイドビルド(int型L、int型のR、int型K) { ツリー[K] .L = L;ツリー[K] .R = R。 (L == R)戻った場合。 (リットル、ミッド、LC)を構築します。 (ミッド+ 1、R、RC)を構築します。 } ボイドプッシュダウン(int型K) { ツリー[LC] .TAG + =ツリー[K] .TAG。 ツリー[RC] .TAG + =ツリー[K] .TAG。 ツリー[LC] .W + =(ツリー[LC] .Rツリー[LC] .L + 1)*ツリー[K] .TAG。 ツリー[RC] .W + =(ツリー[RC] .Rツリー[RC] .L + 1)*ツリー[K] .TAG。 ツリー[K] .TAG = 0。 返します。 } ボイド押し上げ(int型K) { ツリー[K] .W =ツリー[LC] .W +ツリー[RC] .W。 返します。 } ボイド追加(int型のx、int型のY、int型K) { int型L =ツリー[K] .L、R =ツリー[K] .R。 IF(L> = X && R <= Y) { ツリー[K] .TAG + = Z。 ツリー[K] .W + =(R-L + 1)* Z。 返します。 } IF(ツリー[K] .TAG)プッシュダウン(K)。 IF(X <= MID)(X、Y、LC)を追加します。 (Y>中間)が追加した場合(X、Y、RC)。 突き上げ(K)。 } int型の照会(int型のx、int型のY、int型K) { int型L =ツリー[K] .L、R =ツリー[K] .R。 IF(L> = X && R <= Y) { 戻りツリー[K] .W。 } IF(ツリー[K] .TAG)プッシュダウン(K)。 int型のres = 0; (X <= MID)RES + =クエリ(X、Y、LC)であれば、 もし(Y> MID)RES + =クエリ(X、Y、RC)。 解像度を返します。 } Taddでは(int型のx、int型のy)を無効 { 一方(上面[X] = TOP [Y]!) { IF(DEP [TOP [X] <DEP [トップ[Y])スワップ(X、Y) 追加(SEG [TOP [X]、SEG [x]は、1)。 X = FA [TOP [X]]。 } IF(DEP [X]> DEP [Y])スワップ(X、Y) 追加(SEG [x]は、SEG [Y]、1)。 } INT Treequery(INT X) { 戻りクエリ(SEG [x]は、SEG [X] +サイズ[X] -1,1)。 } )(主符号付き { N =読み取ります()。 以下のために(; iがn <I ++はI = 1 INT) { X =リード(); Yは、読み取り=(); X ++; Y ++。 (x、y)を追加し、(x、y)を加えます。 } DFS1(1,0); DFS2(1,1)。 (1、nは、1)を構築します。 M =読み取ります(); 一方、(M--) { cinを>> Q; IF(Q == 'A') { X =リード(); Yは()を読み取る。=; Zは読み取り=(); X ++; Y ++。 TADD(X、Y) } 他 { X =リード()。 X ++; COUT << Treequery(X)<< ENDL。 } } }