乙個純虛樹的模板吧,不涉及啥要處理的東西。
題目描述
給定一棵 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並...