P5658ブラケットツリー
問題の解決策
あまりにも多くの食べ物、結果としてできない書き込みデータだけ水5分
その結果、問題への書き込み説明ソリューションは、私が間違っていた大幅に変えることができません。
我々はそれを手動で法律を見つけます
私たちは、あるノードiには、ルートノードからの回答に[i]の貢献、wを設定し、ノードI、法的括弧文字列とに来て、いくつかのより多くの
SUM [i]は、ルートノードからノードへのI 合計括弧正規シーケンス番号
()()()
W [i]は、順次010203あります
和[I]を順次011336あります
()())
W [i]は、順次01001であります
和[I]を順次01112であります
()(())
W [i]は、順次010012あります
和[I]を順次011124あります
私たちは、その後、驚くほどの和[i]とは、[i]と接頭辞wがあることがわかりました
最後の要件は、すべての合計で実際にある[I] * I XORと、W [i]はの解決のための唯一の方法を見つけることが不可欠です
(1)は、S [i]は、左括弧である場合、明らかに新しい貢献= 0 W [i]は、つまり、表示されていないが存在するであろうことを見出しました
(2)S [i]は右括弧で、我々は1閉じ括弧の貢献の価値を発見した場合、貢献は彼の対応の右括弧にある:実際には、現在の閉じ括弧のために、同等である、(条件ならばそれは、答えの寄与は右括弧の前に1、現在のガチョウ右括弧で)彼は左括弧のマッチングを持っている、これは彼が一定の貢献に回答する必要があり、加えて、ブラケットの現在の新しいマッチしたペアになる許可します新しい文字列マッチングブラケットを生成し、その後、私たちは保存することが閉じ括弧への貢献として、それを紹介します
)()()()():栗の場合
W [4] = 2
S [5]それはS [5]とみなされ、新しいマッチがブラケットを発生しないので、[5] = 0 wは次に、左括弧であります
新しいマッチング括弧を形成するためにS [6]の可能なマッチング右括弧であり、その後、S [5]及びS [6]、S [3]〜S [6]及びS [1]〜S [6]であります新しいブラケットが一致する、彼らが新たなブラケットの列からなる新規追加S [5] S [6]に基づいて、元のW [4]であります
S [7]は、左括弧に一致しない、W [7] = 0
S [9]右上の括弧は今オリジナル+に基づく中間体が切断されるため、[9]だけ、貢献として括弧文字列を夢ことができる時間で接触するので、S S [7]であるため、 ()括弧の新しい文字列を生成することができます
の値に対応するツリーノードに沿ってDFSを再帰的更新を使用して
コード
書式#include <iostreamの> の#include <cstdioを> する#include <cstdlib> 書式#include <アルゴリズム> 書式#include <cmath> の#include < 文字列 > の#include <CStringの> の#include <キュー> 使用して名前空間はstdを、 typedefの長い長いLL。 インラインint型リード() { int型 ANS = 0 。 チャー最後=を' '、CH = GETCHAR()。 しばらく(CH < ' 0 ' || CH> 9 ')最後= CH、CH = GETCHAR()。 一方、(CH> = ' 0 ' && CH <= ' 9 ')ANS = ANS * 10 + CH- ' 0 '、CH = GETCHAR()。 もし(最後== ' - ')ANS = - ANS; 戻り値は、ANS; } CONST INT MAXN = 5E5 + 10 。 LL N、ANS = 0 。 チャーS [MAXN]。 LL FA [MAXN]。 事前[MAXN]、W [MAXN]っ。 LL CNT = 0、ヘッド[MAXN]、[MAXN <<に1 ]、NXT [MAXN << 1 ]。 ボイド addedge(INT U、INT V) { [に対して ++ CNT] = V; NXT [CNT] =頭部[U];頭部[U] = CNT。 } ボイド DFS(INT U) { 事前[U] = 予備[FA [U]。 もし(S [U] == ' (')プレ[U] = U; そう であれば(PRE [U]){ W [U] = [FA [プレ[U]]] + wは1、[U]を事前に= ;プレ[FA [プレ[U]]] } のために(INT iはヘッド= [U]; I; I =NXT [i])とDFS(の[I])。 } int型)(主 { N = (読み取り) scanf関数(" %S "、S + 1 )。 以下のために(INT iが= 2 ; I <= N; I ++ ){ FA [I] = )(読み取ります。 addedge(FA [i]は、I)。 } DFS(1 )。 ANS = W [ 1 ]。 以下のために(INT iが= 2 ; I <= N; I ++ ){ W [I] + = W [FA [I]]。 ANS ^ =(i *が [I] W) } printf(" %のLLD \ n " 、ANS)。 リターン 0 ; }
-------------------------
CSP 2019 D1T2