51nod 1681公共祖先

2021-08-09 14:30:59 字數 1524 閱讀 8043

1681 公共祖先

有乙個龐大的家族,共n人。已知這n個人的祖輩關係正好形成樹形結構(即父親向兒子連邊)。

在另乙個未知的平行宇宙,這n人的祖輩關係仍然是樹形結構,但他們相互之間的關係卻完全不同了,原來的祖先可能變成了後代,後代變成的同輩……

兩個人的親密度定義為在這兩個平行宇宙有多少人一直是他們的公共祖先。

整個家族的親密度定義為任意兩個人親密度的總和。

input

第一行乙個數n(1<=n<=100000)

接下來n-1行每行兩個數x,y表示在第乙個平行宇宙x是y的父親。

接下來n-1行每行兩個數x,y表示在第二個平行宇宙x是y的父親。

output

乙個數,表示整個家族的親密度。

input示例

5 1 3

3 5

5 4

4 2

1 2

1 3

3 4

1 5

output示例

6 ﹡ lh (題目提供者) df

s序+樹

狀陣列

考慮以u

為祖先有

幾對人一

直是他兒

子 先d

fs1第

一棵樹,

記錄df

s序 再

dfs2

第二顆樹

,用樹狀

陣列維護

,u的兒

子中有幾

個區間是

在u的區

間裡面的

#include

#include

using

namespace

std;

#define n 100010

#define ll long long

#define lowbit(x) ((x)&(-x))

int n;

struct nodestack[n];

int vet[n],next[n],hed[n],h[n],in[n];

ll ans;

int num,cnt;

void add(int x)

int get(int x)

void edgeadd(int u,int v)

void dfs1(int u,int fa)

stack[u].r=cnt;

}void dfs2(int u,int fa)

int nowr=get(stack[u].r)-get(stack[u].l-1);

ans+=(ll)(nowr-nowl)*(nowr-nowl-1)/2;

}void read(int ha)

int root=0;

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

if (in[i]==0)

if (!ha) dfs1(root,0);

else dfs2(root,0);

}int main()

51nod1681 公共祖先

1681 公共祖先 基準時間限制 1 秒 空間限制 131072 kb 分值 80 難度 5級演算法題 有乙個龐大的家族,共n人。已知這n個人的祖輩關係正好形成樹形結構 即父親向兒子連邊 在另乙個未知的平行宇宙,這n人的祖輩關係仍然是樹形結構,但他們相互之間的關係卻完全不同了,原來的祖先可能變成了後...

公共祖先 51Nod 1681

給兩棵樹 問對於每對頂點 有多少除這兩個點之外的點 在這兩棵樹上都是這兩個點的公共祖先 考慮每個點的貢獻 對於乙個點 其子樹在兩棵樹上的有兩個dfs序 就看這兩個序列有多少數是相同的 c n,2 一下即可 至於查詢兩個序列的兩個區間有所少數是相同的 主席樹搞一下就行 這有個這型別的裸題 先把這個做明...

1681 公共祖先

有乙個龐大的家族,共n人。已知這n個人的祖輩關係正好形成樹形結構 即父親向兒子連邊 在另乙個未知的平行宇宙,這n人的祖輩關係仍然是樹形結構,但他們相互之間的關係卻完全不同了,原來的祖先可能變成了後代,後代變成的同輩 兩個人的親密度定義為在這兩個平行宇宙有多少人一直是他們的公共祖先。整個家族的親密度定...