P3806 模板 點分治1

2022-05-03 13:03:23 字數 1907 閱讀 7639

感謝hzwer的點分治互測。

給定一棵有n個點的樹

詢問樹上距離為k的點對是否存在。

輸入格式:

n,m 接下來n-1條邊a,b,c描述a到b有一條長度為c的路徑

接下來m行每行詢問乙個k

輸出格式:

對於每個k每行輸出乙個答案,存在輸出「aye」,否則輸出」nay」(不包含引號)

輸入樣例#1: 複製

2 1

1 2 2

2

輸出樣例#1: 複製

aye

對於30%的資料n<=100

對於60%的資料n<=1000,m<=50

對於100%的資料n<=10000,m<=100,c<=1000,k<=10000000

//

pro:p3806 【模板】點分治1

//寫一篇與他們做法不同的題解

//這個做法像 p4178 tree 差不多

//仍然是存下所有的詢問,離線操作

//我們用flag[i]表示第i個詢問能滿足的次數

//在分治的時候,仍然是先處理父親,再容斥處理減掉兒子

//如果都處理完之後flag[i]仍然是》0的,那就說明存在這樣一條路徑,否則就不存在

//複雜度的話,應該是m*nlogn+nlog^2n的吧 不太會算

#include

#include

#include

#include

#include

using

namespace

std;

inline

intread()

const

int n=1e4+5

;const

int m=1e7+5

;const

int inf=599518803

;int

n,m;

intk[n];

inthead[n],num_edge;

struct

edge

edge[n

<<1

];inline

void add_edge(int u,int v,int

w)bool

vis[n];

intflag[m];

intsiz,root;

intmxson[n],siz[n];

void getroot(int u,int

fa) mxson[u]=max(mxson[u],siz-siz[u]);

if(mxson[u]root=u;

}int

dep[n],dis[n],cnt;

void getdis(int u,int

fa)}

void solve(int u,int dist,int val) //

val表示是加還是容斥減掉

else

//else

//rr=mid-1;//}

//int a=pos-l+1;

//l=pos+1;

//ll=l,rr=r,pos=rr;

//while(ll<=rr)

////

flag[i]+=val*a*(r-pos+1);

//r=pos-1;

} }}}

}void divide(intu)}

intmain()

for(int i=1;i<=m;++i)

k[i]=read();

siz=n,mxson[0]=inf;

getroot(

1,1);

divide(root);

for(int i=1;i<=m;++i)

return0;

}

P3806 模板 點分治1

給定一棵有 n 個點的樹,詢問樹上距離為 k 的點對是否存在。關於點分治具體內容可以看這個 這裡主要是詳細講講 getrt是用來求重心,我們利用樹型dp的思維來做,即找到該節點所有的子樹,找到最大的哪一顆即可 void getrt int u,int pa 求重心 maxp u max maxp u...

P3806 模板 點分治1

感謝hzwer的點分治互測。給定一棵有n個點的樹 詢問樹上距離為k的點對是否存在。輸入格式 n,m接下來n 1條邊a,b,c描述a到b有一條長度為c的路徑 接下來m行每行詢問乙個k 輸出格式 對於每個k每行輸出乙個答案,存在輸出 aye 否則輸出 nay 不包含引號 輸入樣例 1 2 1 1 2 2...

P3806 模板 點分治1

p3806 模板 點分治1 定一棵有 n 個點的樹,多次詢問樹上距離為 k 的點對是否存在。澱粉質模板題。澱粉質的核心就是其只統計經過當前根結點的路徑,即可以把兩條路徑 拼 起來,同時分治結構保證了其只有 log 次這樣的計算。常用於統計樹上點對數量這樣的問題。來看這道題。可以對每乙個路徑長度開乙個...