BZOJ 3251 樹上三角形

2022-05-19 07:50:14 字數 1310 閱讀 8290

傳送門

看到這種奇怪的要求,考慮一下推結論

考慮把路徑上的點權拿出來排序,變成乙個數列,那麼顯然我們只要考慮相鄰連續的 $3$ 個數

發現如果我們貪心構造乙個盡量無法構成三角形的數列,那麼最小的數列就是斐波那契數列

眾所周知斐波那契數列增長很快,第 $50$ 項顯然遠大於題目給出的點權範圍,所以如果 $u,v$ 之間點數大於等於 $50$,那麼鴿巢原理一下顯然一定能構成三角形

所以如果 $u,v$ 之間點數超過 $50$ 直接輸出 $y$ 即可,否則我們再暴力判斷即可

這個實現就一倍增 $lca$ 

#include#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;inline

intread()

while(ch>='

0'&&ch<='

9')

return x*f;

}const

int n=2e5+7

;int fir[n],from[n<<1],to[n<<1

],cntt;

inline

void add(int a,int b)

intn,m,a[n];

int dep[n],f[n][21

];void dfs(intx)}

int lca(int x,int

y)int tmp[57

],tot;

intmain()

int lca=lca(x,y); if(dep[x]+dep[y]-2*dep[lca]>=50)

tmp[tot=1]=a[lca];

while(x!=lca) tmp[++tot]=a[x],x=f[x][0

];

while(y!=lca) tmp[++tot]=a[y],y=f[y][0

]; sort(tmp+1,tmp+tot+1); bool gg=0

;

for(int i=3;i<=tot;i++)

if(1ll*tmp[i-2]+tmp[i-1]>1ll*tmp[i])

if(gg) printf("

y\n"

);

else printf("

n\n"

); }

return0;

}

bzoj3251 樹上三角形

給定一大小為n的有點權樹,每次詢問一對點 u,v 問是否能在u到v的簡單路徑上取三個點權,以這三個權值為邊長構成乙個三角形。同時還支援單點修改。第一行兩個整數n q表示樹的點數和運算元 第二行n個整數表示n個點的點權 以下n 1行,每行2個整數a b,表示a是b的父親 以1為根的情況下 以下q行,每...

bzoj3251 樹上三角形

題意 有根樹,支援兩種操作,詢問從u v的簡單路徑上是否存在三個點權可以構成三角形,單點修改點權。暑假多校的時候就見過這個斐波那契性質。兩邊之和大於第三邊,顯然這是個很套路的東西,這個性質就是斐波那契性質,而斐波那契數列至多在五十項左右的時候炸int,故若簡單路徑長度大於50,那麼必然有解,否則暴力...

bzoj3251 樹上三角形

傳送門 題目 給定一大小為n的有點權樹,每次詢問一對點 u,v 問是否能在u到v的簡單路徑上取三個點權,以這三個權值為邊 長構成乙個三角形。同時還支援單點修改。input 第一行兩個整數n q表示樹的點數和運算元 第二行n個整數表示n個點的點權 以下n 1行,每行2個整數a b,表示a是b的父親 以...