jzoj1166 樹中點對距離 點分治

2021-09-25 04:55:20 字數 1515 閱讀 5988

求一棵樹上有多少條路徑長度≤le

n\leq len

≤len

首先普通點分治。掃瞄的時候將每個點儲存為乙個二元組(di

s,gr

a)

(dis,gra)

(dis,g

ra)分別表示離(分治到的)根的距離,屬於根的那顆子樹。

然後按照dis

disdi

s排序,兩個指標l,r

l,rl,

r用cn

icn_i

cni​

表示[ l+

1,r]

[l+1,r]

[l+1,r

]這個區間內是i

ii這個子樹的點的個數。

然後我們發現滿足dis

l+di

sr≤l

en

dis_l+dis_r\leq len

disl​+

disr

​≤le

n這個範圍根據l

ll的向前r

rr是單調不公升的然後兩個指標維護一下每次統計一下答案r−l

−cnl

r-l-cn_l

r−l−cn

l​

#include

#include

#include

using

namespace std;

const

int n=

100100

;struct nodea[n*3]

;struct num_nodenum[n]

;int siz[n]

,ls[n]

,v[n]

,root,len,n,f[n]

,ans,tot,x,y,w,cnt,cn[n]

;bool

cmp(num_node x,num_node y)

void

addl

(int x,

int y,

int w)

void

groot

(int x,

int fa)

f[x]

=max

(f[x]

,n-siz[x]);

if(f[x]

) root=x;

}void

dfs(

int x,

int fa,

int w,

int grafa)

voiddp(

int x)

for(

int i=ls[x]

;i;i=a[i]

.next)if(

!v[a[i]

.to])}

intmain()

f[0]=

2147483647

;groot(1

,0);

dp(root)

;printf

("%d"

,ans)

;}

JZOJ 1166 樹中點對距離

給出一棵帶邊權的樹,問有多少對點的距離 le n 2 n 10000 len 231 這是一道十分經典的點分治題目。點分治,顧名思義,就是按照點來分治。假設當前要計算某棵子樹裡面滿足題目條件的點對數,我們可以先找出這棵子樹的重心。易知,此棵子樹的點對數 經過重心的合法點對數 不經過重心的合法點對數。...

樹中點對距離(點分治)

給出一棵帶邊權的樹,問有多少對點的距離 len 這是一道點分治的經典題目,可以給點分治的初學者練手。點分治,顧名思義就是把每個點分開了處理答案。假設,目前做到了以x為根的子樹。先求出子樹中每個點到根的距離di s 對於兩個點 i 和 j,如果di si d isj k 那麼 i j 就是乙個合法的點...

樹中點對距離

在一顆n個結點的樹上,統計有多少點對最短距離 m。點對不存在順序性 n 10000 我們選取乙個點x作根,那麼任何點對都分成兩種型別 1 經過x 2 不經過x 我們對經過x的進行統計,對於不經過x的繼續在x的子樹中分治下去。這就是點分治。我們處理出每個點的深度,排序後就很容易統計經過x的個數。不過有...