fzoj 2119 祖先問題

2022-08-19 14:54:15 字數 1467 閱讀 8216

problem 2119 祖先問題

有n個結點構成了多棵樹,給出每個結點的父節點,若為-1則表示該結點無父節點。每個結點的父節點編號必須比該結點的編號小。給m個操作,有兩種操作:1.重新設定某結點的父節點;2.求某結點的祖先個數。乙個結點的祖先為其父節點及其父節點的祖先。

有多組資料輸入。每組資料的第一行為兩個整數n,m。(1<=n,m<=200000)。第二行輸入n個數,從1到n分別表示編號為1到n的結點的父節點,若為-1則表示該結點無父節點。接下來輸入m行,表示m個操作,每行輸入有兩種:三個數t,a,b(t=0,1<= a <=n,b為-1或小於a的正整數),將結點a的父節點設定為b,若b為-1則表示將a設為無父節點;或者兩個數t,a(t=1,1<=a<=n),表示詢問結點a的祖先個數。資料保證每個結點的父節點編號比該結點小。所有輸入都為整數。

對於每個詢問輸出一行乙個整數,表示該結點的祖先數。

4 3-1 1 2 3

1 40 4 1

1 43

1foj有獎月賽-2023年4月(校賽熱身賽)

思路:lct裡面的access操作是把 自己到根的邊置為重邊,這樣我們就可以直接用lct搞了

#pragma comment(linker,"/stack:1024000000,1024000000")#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 0x3f3f3f3f

#define maxn 200010

#define eps 1e-6

#define mod 1000000007

using

namespace

std;

struct

lct

void update(int

x )

bool isroot(int

x )

void rotate(int x,int

f)

void splay(int

x)

}update(x);

}void access(int

u)

ff=f;

}void cut(int x,int

y )

int find(int

x)

}lct;

intfa[maxn] ;

intmain()

while(m--)

else}}

return0;

}

view code

最近公共祖先問題

最近公共祖先 least common ancestors 問題是面試中經常出現的乙個問題,這種問題變種很多,解法也很多。最近公共祖先問題的定義如下 對於有根樹t的兩個結點u v,最近公共祖先lca t,u,v 表示乙個結點x,滿足x是u v的祖先且x的深度盡可能大。另一種理解方式是把t理解為乙個無...

最近公共祖先問題

在樹中尋找兩個結點的最近公共祖先 從樹的根節點開始進行深度優先搜尋,每次經過某乙個點 無論是從它的父親節點進入這個點,還是從它的兒子節點返回這個點,都按順序記錄下來。這樣就把一棵樹轉換成了乙個陣列。而找到樹上兩個節點的最近公共祖先,無非就是找到這兩個節點最後一次出現在陣列中的位置所囊括的一段區間中深...

最近公共祖先問題(LCA)

最近公共祖先問題 lca 下面的內容來自演算法藝術與資訊學競賽一書 lca問題 給出乙個有根樹t,對於任意兩個節點u和v,求出 lca t,u,v 即離根最遠的結點x,使得x同時是u和v的祖先。從上面的遞推方法,給我們乙個啟示。當l u l v 時,可以根據lca u,v 的答案把所有結點分成若干個...