樹上三角形 tri

2021-07-05 13:44:52 字數 1536 閱讀 9444

時間限制: 1 sec 記憶體限制: 256 mb

題目描述

給定一大小為n的有點權樹,每次詢問一對點(u,v),問是否能在u到v的簡單路徑上取三個點權,以這三個權值為邊長構成乙個三角形。同時還支援單點修改

輸入

第一行兩個整數n、q表示樹的點數和運算元

第二行n個整數表示n個點的點權

以下n-1行,每行2個整數a、b,表示a是b的父親(以1為根的情況下)

以下q行,每行3個整數t、a、b

若t=0,則詢問(a,b)

若t=1,則將點a的點權修改為b

輸出

對每個詢問輸出一行表示答案,「y」表示有解,「n」表示無解

樣例輸入

5 5

1 2 3 4 5

1 2

2 3

3 4

1 5

0 1 3

0 4 5

1 1 4

0 2 5

0 2 3

樣例輸出

n y y n

【資料範圍】

對於10%的資料,n,q<=100

對於另外40%的資料,無修改操作

對於100%的資料,n,q<=100000,點權範圍[1,2^31-1]

三條邊形成乙個三角形必然被滿足a+b>=c。當a+b=c,可以發現是乙個斐波那契數列,鑑於點權<2^31-1,即為斐波那契第47項。所以當兩點間節點數超過47,則必然滿足題意。對於節點數小於47的部分包裡判斷即可。

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define n 100010

using namespace std;

int n,q,s[n],dep[n],t[50],fa[n];

int k,la[n],ff[n*2],q[n];

struct nodemap[n*2];

void add(int a,int b)

; ff[k]=la[a];la[a]=k;

}void bfs()

}int main()

int sum=0,flag=0;

while(a!=b&&sum<47)

if(sum==47)

t[++sum]=s[a];sort(t+1,t+sum+1);

for(int i=1;i<=sum-2;i++)

if((ll)t[i]+t[i+1]>(ll)t[i+2])

if(!flag)printf("n\n");

else

printf("y\n");

} return

0;}

樹上三角形

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

樹上三角形

題目描述 給定乙個大小為n的有點權樹,需要支援兩個操作。0 詢問 u,v 能否在u到v的簡單路徑上取三個點,使這三個點的點權作為邊長可以構成乙個三角形。1 修改某個點的點權。輸入格式 第一行兩個整數n,q表示樹的點數和運算元。第二行n個整數表示n個點的初始的點權。接下來n 1行,每行兩個整數a,b,...

3251 樹上三角形

題目鏈結 題目大意 給定一大小為n的有點權樹,每次詢問一對點 u,v 問是否能在u到v的簡單路徑上取三個點權,以這三個權值為邊長構成乙個三角形。同時還支援單點修改。題解 看到題目果斷開始想資料結構,感覺要上lct?蒟蒻表示不會 膜了一發題解後。考慮這樣乙個問題 有乙個數列,數列中的數滿足題目條件,那...