感謝hzwer的點分治互測。
給定一棵有n個點的樹
詢問樹上距離為k的點對是否存在。
輸入格式:
n,m 接下來n-1條邊a,b,c描述a到b有一條長度為c的路徑
接下來m行每行詢問乙個k
輸出格式:
對於每個k每行輸出乙個答案,存在輸出「aye」,否則輸出」nay」(不包含引號)
輸入樣例#1: 複製
2 11 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 次這樣的計算。常用於統計樹上點對數量這樣的問題。來看這道題。可以對每乙個路徑長度開乙個...