P6135 模板 虛樹

2021-10-03 06:54:08 字數 1905 閱讀 6585

乙個純虛樹的模板吧,不涉及啥要處理的東西。

題目描述

給定一棵 n 個點的有根樹,樹上有 k 個關鍵點,請你構建這些點的虛樹。

輸入格式

第一行兩個整數 n,k。

第二行 n 個整數 f 1…n,其中 fi 表示 i 的父親。特別地,若 i 為根,則 fi =0。

第三行 k 個整數,表示關鍵點。

輸出格式

共 n 行,第 i 行兩個整數 gi, di

若 i 不在虛樹中,則 gi = di = -1

若 i 為虛樹的根,則 gi = di = 0

若 i 在虛樹中但不為根,則 gi 為 i 在虛樹中的父親,di表示 i 和 gi在原樹中的距離。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define llu unsigned ll

using

namespace std;

const

double eps =

1e-8

;const ll lnf =

0x3f3f3f3f3f3f3f3f

;const

int inf =

0x3f3f3f3f

;const

int maxn =

200100

;const

int mod =

1e9+7;

int head[maxn]

, ver[maxn]

, nt[maxn]

;int fa[maxn]

, d[maxn]

, f[maxn][22

], dfn[maxn]

, a[maxn]

,s[maxn]

;int t, tot =

1, cnt =

0, top =0;

int n, k, x, rt;

void

add(

int x,

int y)

bool

cmp(

const

int& a,

const

int& b)

void

dfs(

int x)

}int

lca(

int x,

int y)

voidin(

int x)

int lca =

lca(s[top]

, x);if

(lca == s[top]

)while

(top >

1&& dfn[s[top -1]

]>= dfn[lca])if

(lca != s[top]

) fa[s[top]

]=lca, s[top]

= lca;

s[++top]

= x;

}void

build

(int k)

intmain

(void

)memset

(fa,-1

,sizeof

(fa));

d[rt]=1

;dfs

(rt)

;build

(k);

for(

int i =

1;i <= n;i++

)return0;

}

虛樹模板詳解和例題

虛樹 原樹中給一些點,通過一些lca把它們重新連線在一起建成一棵新樹,相當於對樹進行了化簡。新樹邊上的資訊可以用樹鏈剖分 倍增等維護。如何建虛樹 假設給出的點都存在d陣列裡。對於這些點,按照它們在原樹中的dfs序從小到大排個序。然後我們建乙個棧,從棧底到棧頂相當於是一條當前虛樹根一直往下走的鏈。遍歷...

P3373 線段樹模板

如題,已知乙個數列,你需要進行下面三種操作 1.將某區間每乙個數乘上x 2.將某區間每乙個數加上x 3.求出某區間每乙個數的和 輸入格式 第一行包含三個整數n m p,分別表示該數列數字的個數 操作的總個數和模數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包...

P3377 左偏樹,模板)

題意 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 1並...