給定一棵 n 個點的有根樹。
有 q 次詢問,第 i 次詢問給定 xi, ki,要求點 xi 的 ki 級祖先。
保證ki合法。
一、樹鏈剖分——重鏈剖分 o(n+qlogn):
7.46s
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define llu unsigned ll
using
namespace std;
#define ui unsigned int
ui s;
inline ui get
(ui x)
const
int maxn=
500100
;int head[maxn]
,ver[maxn]
,nt[maxn]
;int f[maxn]
,d[maxn]
,si[maxn]
,son[maxn]
,rk[maxn]
;int top[maxn]
,id[maxn]
,vi[maxn]
;int tot=
1,cnt=
0,n,q,rt;
void
add(
int x,
int y)
void
dfs1
(int x)
}void
dfs2
(int x,
int t)
}intfi(
int x,
int k)
return rk[id[x]
-k];
}int
main
(void
) d[rt]=1
;dfs1
(rt)
;dfs2
(rt,rt)
; ui ans=0;
ll res=0;
for(
int i=
1;i<=q;i++
)printf
("%lld\n"
,res)
;return0;
}
二、樹鏈剖分——長鏈剖分 o(nlogn + q):
12.31s
大概是我姿勢不太對。
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define llu unsigned ll
using
namespace std;
#define ui unsigned int
ui s;
inline ui get
(ui x)
const
int maxn=
500100
;int head[maxn]
,ver[maxn]
,nt[maxn]
;int f[maxn][22
],d[maxn]
,h[maxn]
,son[maxn]
;int top[maxn]
,id[maxn]
,lo[maxn]
,up[maxn]
,down[maxn]
;int tot=
1,cnt=
0,n,q,rt,t;
void
add(
int x,
int y)
void
dfs1
(int x)
}void
dfs2
(int x,
int t,
int p)
}intfi(
int x,
int k)
intmain
(void
) d[rt]
=h[rt]=1
,t=log2
(n)+1;
dfs1
(rt)
;dfs2
(rt,rt,rt)
; ui ans=0;
ll res=0;
for(
int i=
1;i<=q;i++
)printf
("%lld\n"
,res)
;return0;
}
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並...
P6135 模板 虛樹
乙個純虛樹的模板吧,不涉及啥要處理的東西。題目描述 給定一棵 n 個點的有根樹,樹上有 k 個關鍵點,請你構建這些點的虛樹。輸入格式 第一行兩個整數 n,k。第二行 n 個整數 f 1 n,其中 fi 表示 i 的父親。特別地,若 i 為根,則 fi 0。第三行 k 個整數,表示關鍵點。輸出格式 共...