luogu3379 最近公共祖先

2021-08-18 06:45:40 字數 1495 閱讀 5075

題目描述

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。

輸入輸出格式

輸入格式:

第一行包含三個正整數n、m、s,分別表示樹的結點個數、詢問的個數和樹根結點的序號。

接下來n-1行每行包含兩個正整數x、y,表示x結點和y結點之間有一條直接連線的邊(資料保證可以構成樹)。

接下來m行每行包含兩個正整數a、b,表示詢問a結點和b結點的最近公共祖先。

輸出格式:

輸出包含m行,每行包含乙個正整數,依次為每乙個詢問的結果。

輸入輸出樣例

輸入樣例#1:

5 5 4

3 1

2 4

5 1

1 4

2 4

3 2

3 5

1 2

4 5

輸出樣例#1:

4 4

1 4

4 說明

時空限制:1000ms,128m

資料規模:

對於30%的資料:n<=10,m<=10

對於70%的資料:n<=10000,m<=10000

對於100%的資料:n<=500000,m<=500000

樣例說明:

該樹結構如下:

第一次詢問:2、4的最近公共祖先,故為4。

第二次詢問:3、2的最近公共祖先,故為4。

第三次詢問:3、5的最近公共祖先,故為1。

第四次詢問:1、2的最近公共祖先,故為4。

第五次詢問:4、5的最近公共祖先,故為4。

故輸出依次為4、4、1、4、4。

當年寫的神奇的lct做法

#include

#define n 550000

inline int

read()

returnx;}

int ans,top,n,m,s;

int father[n],child[n][2],rev[n],q[n];

bool isroot(int

x)inline void swap(int &x,int &y)

void pushdown(intx)}

void rotate(int

x)void splay(int

x) while(top) pushdown(q[top--]);

while (!isroot(x))

rotate(x);

}}void access(intx)}

void makeroot(int

x)void link(int u,int v)

int main()

makeroot(s);//注意換為題目要求的根

//for (int i=1;i<=n;++i) printf("%d ",father[i]);

for (int i=1;i<=m;++i)

return

0;}

P3379最近公共祖先(LCA)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。輸入格式 第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問...

P3379 模板 最近公共祖先(LCA)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問a結點和b...

P3379 模板 最近公共祖先(LCA)

如題,給定一棵有根多叉樹,請求出指定兩個點直接最近的公共祖先。第一行包含三個正整數n m s,分別表示樹的結點個數 詢問的個數和樹根結點的序號。接下來n 1行每行包含兩個正整數x y,表示x結點和y結點之間有一條直接連線的邊 資料保證可以構成樹 接下來m行每行包含兩個正整數a b,表示詢問a結點和b...