Luogu P3806點分治模板(點分治)

2022-05-01 01:12:15 字數 1743 閱讀 1484

題目鏈結

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 的點對。這道題我們用分治的方法。那我們假設要解決乙個樹,那我們先選重心作為根節點 為了減少高度節省時間 然後就分成兩種討論,一種是路徑都在同乙個子樹中,那這個我們就可以把問題轉換為解決這個子樹。另一種就是在兩個不同的子樹中 ...