題目鏈結
wc聽不懂lca講的高等數學專場(乙個字都聽不懂),然後就自學了點分治。
點分治就是我先處理完跟根有關的東西,然後把根標記掉,把原樹拆成若干個聯通塊,然後分別對每個聯通塊(每個小樹)搞一模一樣的操作。
然後要每次求重心,因為點分治複雜度跟遞迴深度有關。
本題判斷的時候偷懶用map,其實自己寫的splay也快不到**去的樣子。qwq。
#include#include#include
#include
#include
#include
#define maxn 200020
using
namespace
std;
inline
long
long
read()
while
(isdigit(ch))
return num*f;
}struct
edgeedge[maxn*3
];int
head[maxn],num;
inline
void add(int
from,int to,int
val);
head[
from]=num;
}map
ext;
bool
tag[maxn];
intsize[maxn];
intmxn[maxn];
intstack[maxn],top;
intd[maxn];
intw[maxn];
int root=0
;void getroot(int x,int fa,int
lim)
if(retsize[x];
mxn[x]=ret;
if(ret0) root=x;
}void depfind(int x,int fa,int
dst)
return;}
int getsize(int x,int
fa)
return
ans;
}void dfs(int x,int lim,int
m) }
for(int j=1;j<=top;++j) ext[stack[j]]=1
; }
int now=root;
for(int i=head[now];i;i=edge[i].next)
}int
main()
for(int i=1;i<=m;++i) d[i]=read();
dfs(
1,n,m);
for(int i=1;i<=m;++i)
if(w[i]==1) printf("
aye\n");
else printf("
nay\n");
return0;
}/*13 10
1 2 1
1 4 2
4 3 5
4 5 11
5 6 4
5 7 2
4 8 7
1 10 2
9 10 9
1 11 4
11 13 5
11 12 6
1211109
8221314
1518
*/
luogu P3806 模板 點分治1
題目描述 給定一棵有n個點的樹 詢問樹上距離為k的點對是否存在。多次詢問 可離線 我們先隨意指定乙個虛擬根root,將這棵樹轉化成無根樹 樹上的路徑可以分為兩類,1.經過根節點u的路徑 2.完全在u子樹裡 不經過u 的 對於1,用dis表示當前結點到根節點root的路徑長度,則root的子樹中兩個節...
Luogu P3806 模板 點分治1
給定一棵有 n nn 個點,邊權的樹,回答 m mm 個詢問,每次詢問樹上距離為 k kk 的點對是否存在。資料範圍n 1 04,m 100,邊權 10000,k 107 n leqslant 10 4,m leqslant 100,texttt leqslant 10000,k leqslant ...
luogu P3806 模板 點分治1
給你一棵樹,路徑有長度,多次詢問,每次給出 k,問你是否存在路徑長度為 k 的點對。這道題我們用分治的方法。那我們假設要解決乙個樹,那我們先選重心作為根節點 為了減少高度節省時間 然後就分成兩種討論,一種是路徑都在同乙個子樹中,那這個我們就可以把問題轉換為解決這個子樹。另一種就是在兩個不同的子樹中 ...