はじめに:
まず、最良の第1の分割ツリーチェーンLCA、ツリー-DPを学習する前に、これら三つの知識のDFSシーケンスが学んだ
チェーンが主演する前に、EMMはまだ必要な、ツリーラインも最初に学びました。
これら3点は知識が良いです把握していなかった場合は、ツリー鎖分割は、もちろん理解することは困難です。
I.はじめに
ツリーチェーンが木のいくつかのチェーンに分割され、ツリーは、処理を減らすことの難しさを直線的になり
問題は対処が必要です。
-
- XからY最短経路ノード値プラスZへのすべてのツリーノード
- すべてのノードのyの値に対するXからノードの最短経路のツリー要求と
- Xは、ルートノードはサブツリー・ノードの値であるすべてのプラスZであろうあります
- xは、サブツリーのルートノードである値のすべてのノードを検索し
コンセプト
-
- ヘビー息子:各非リーフノードの場合、その息子長男の息子に、PS(再息子ノードのルートサブツリーノードです:感謝@shzr首長は、この文は私の厳格を発現しない指摘qwq、修正)
- ライト息子:各非リーフノードの場合、それは残りの重いすべてのアフリカの息子の息子がいるが、光の息子の息子であります
- リーフノードは、(それが息子を持っていないので...)光や重い息子の息子をしません
- ヘビーサイド:彼の父の息子ヘビーエッジへの接続は、複数のエッジ//オリジナルの言葉遣いと呼ばれています:任意の2人の息子が重い側縁と呼ばれる再接続
- ライト側:残りの部分は光側であります
- 重鎖:重鎖を接続するリンクに隣接重い側は、重鎖の息子と呼ばれます
- それは光の子である場合、リーフノードのために、出発点は、チェーン1の長さ自体に存在します
- 出発点として息子を点灯させる各重鎖
プロパティ
もしエッジ(U、V)光側と、次いで、サイズ(U)> =サイズ(V)* 2
ログの特定の側面より光複数の経路を介してルート・ノードの数(N)
ログを超えない重鎖一定の経路を経てルートノードの数(N)
第二に、アルゴリズムのプロセス
DFS1()
いくつかのことに対処するDFS1:
-
- 深いマーク各点の深さ[]
- マーク・各ポイントの父FA []
- (自身のを含む)の各非リーフノードラベルされたサブツリーのサイズ
- マーク重い息子番号w_sonの各非リーフノードは、[]
-
インラインボイド DFS1(INT U、INT父、int型fdeep) { ディープ[U] = fdeep、FA [U] =父,, root_size [U] = 1 ; // タグノードの父、深さ、uが現在のルートでありますツリー内のノードの数 int型 pw_son = - 1 ; // -1前提息子root_size重量 のために(int型 ; I I = I =ヘッド[U] エッジ[I] .next) { IF [エッジ( I] == .TO父)続行 ; // 無向グラフ"先祖返り側"は必要ありません DFS1(エッジ[I] .TO、U、fdeepの+ 1。); // 検索息子ノード た場合(root_size [エッジ[I] .TO]> pw_son)w_son [U] = エッジ[I] .TO。 root_size [U] + = root_size [エッジ[i]は.TO]。// 更新重儿子 } }
DFS2()
この前処理はまた、いくつかのことをDFS2
-
- 各ポイントには新しいIDタグません
- 新しい番号上の各点に割り当てられた初期値
- 各ポイントのトップストランドの処理
- 各処理チェーン
-
インラインボイド DFS2(INT U、INT FTOP) { TOP [U] = FTOP; // UはチェーンFTOPの第一鎖に付加される ID [U] = CNT ++; // 各ノードのタイムスタンプを記録する [W CNT] [U] =; //は、タイムスタンプの値に応じて重みを加え IF(!息子[U])のリターン ; // ない息子、直接リターン DFS2(息子[U]、FTOP); // 最初の深い検索重い息子、これは保証することできるだけ小さく重い息子のシーケンス のための(int型 I = haed [U]; I; I = エッジ[I] .next) IF!(エッジ[I] = U && .TOエッジ[I] .TO != ソン[U]) DFS2(エッジ[I] .TO、エッジ[I] .TO)// [i]は.TO新しいチェーンリンクヘッドエッジで発生 }
図に示した図の効果以下のように(遅延少ないです)。
たとえば、次の問題は、テンプレートで対処しました
-
- 処理任意の2点間の正しい道にスポットし、
- 处理一点及其子树的点权和
- 修改任意两点间路径上的点权
- 修改一点及其子树的点权
修改任意两点间路径上的点权
设所在链顶端的深度更深的那个点为x点
-
- ans加上x点到x所在链顶端 这一段区间的点权和
- 把x跳到x所在链顶端的那个点的上面一个点
不停执行这两个步骤,直到两个点处于一条链上,这时再加上此时两个点的区间和即可
处理任意两点间路径上的点权和
修改一点及其子树的点权
处理一点及其子树的点权和
三、例题
四、相关转载于推荐文章(十分感谢这些博主)