要素 [0 からN - 1]を持つ基本的な配列があります。各要素は、配列の前の場所を常に指すインデックスを持つ構造体です。
ある時点で、はるかに大規模なアルゴリズムの一部として、ノードXとそれ以降のノードの間で特定のCの最下位共通祖先を見つけたいと考えています。
int LCA(a, b) {
while (a != b) {
if (a > b) {
a = nodes[a].parent;
} else {
b = nodes[b].parent;
}
}
return a;
}
for (y = x + 1; y < n; ++y) {
if (LCA(x, y) == c) {
//other code
}
}
上記のコードは実際には疑似コードです。使用時にルックアップ テーブルを生成することで、LCA() のパフォーマンスをわずかに改善することができました。このようなもの:
int LCA(a, b) {
if (lookup[a, b]) {
return lookup[a, b];
}
oa = a; ob = b;
while (a != b) {
if (a > b) {
a = nodes[a].parent;
} else {
b = nodes[b].parent;
}
}
lookup[oa, ob] = a;
lookup[ob, oa] = a;
return a;
}
何らかの特殊化された LCA() 関数を作成する方法がある可能性が高いことはわかっています。つまり、上記のすべてのコードを何らかの方法で置き換えて特殊化することで、かなり高速になります。でも、面白いことを思いつきませんでした。
if を見てCとYの間の LCA チェックを簡単に実行できるかどうかを確認しようとしましLCA(c, y) == LCA(x, y)
たが、もちろん正確ではありませんでした。
要約すると、 Xは常にYより小さくなります。Cは常にX (したがってY )より小さくなります。親は常に子よりも低いインデックスになります (したがって、順序付けられます)。
深さを知っているノードはまったく役に立ちますか?
このコードは、合計で約 4 分かかるアルゴリズム全体の CPU 時間の 80% を占めています。これに対する解決策は、アルゴリズム全体を簡単に改善します。ありがとう!