給定乙個大小為 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 51 2 3 4 5
1 22 3
3 41 5
0 1 3
0 4 5
1 1 4
0 2 5
0 2 3ny
yn對於10
%'>10%的資料,n,q
≤100
'>n,q≤100n,q≤100
對於30
%'>30%的資料, n,q
≤1000
'>n,q≤1000n,q≤1000
對於另外40
%'>40%的資料,無修改操作
對於 100
%'>100%的資料, n,q
≤100000
'>n,q≤100000n,q≤100000,點權範圍[1,
231−1
]'>[1,231−1]
題目下來時有人說這題要 tarjan,有說要倍增的,甚至有說要主席樹的。
不過我構造了一下非法情況發現:這個題如果要造乙個最長的非法鏈,那麼鏈上的點的權值排序後一定是斐波那契數列。
為什麼呢?
我們可以這樣來看:
有三個數 a、b、c 已經按照公升序排序,k為正數,那麼根據不等式的性質可得
a-k+b>c 和 a+b>c+k 時,有 a+b>c
所以尋找是否有三個權值可以構成三角形只需要排序後檢查相鄰的三個值,比暴力找尋不知道高到**去了。
因此一條最長的非法鏈權值肯定是斐波那契數列。
我們發現這道題的最大點權為231-1,因此一條非法鏈最大長度為46(再大就會有點權超出題目限制)。
(原諒我開了個掛,其實自己寫也用不了什麼時間)
稍微給點容差,就把長度大於50的鏈直接輸出「y」吧,其餘的暴力。*笑*
至於找lca/求鏈長用最水的乙個就行了。
#include #include#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef
long
long
ll;using
namespace
std;
const
int maxn=110000
;int
n,q;
intw[maxn],dep[maxn],p[maxn];
vector
s[maxn];
void getdep(int
x)
return;}
intmain()
dep[
1]=1; p[1]=-1
; getdep(1);
while(q--)
else
}rd.push_back(w[a]); len++;
if(len>=50) printf("
y\n"
);
else
}if(tri) printf("
y\n"
);
else printf("
n\n"
); }
rd.clear();
}else w[a]=b;
}return0;
}
第三週項 專案1 三角形類1
問題描述 下面設計乙個三角形類,請給出各成員函式的定義 include includeusing namespace std class int main void setabc double x,double y,double z else cout void getabc double x,do...
第三週專案1 三角形類1
問題及 檔名稱 test.cpp 完成日期 2015年3月23日 版 本 號 v1.0 問題描述 下面設計乙個三角形類,請給出各成員函式的定義 程式輸入 程式輸出 include includeusing namespace std class int main else 取三邊的值 void ge...
第三週專案1三角形類1
檔名稱 score.cpp 作 者 惠睿 完成日期 2015年3月25日 版 本 號 v1.0 問題描述 通過指標訪問私有資料成員,進而計算三角形的周長 面積。程式輸入 無輸入。程式輸出 三角形的三條邊 周長 面積。include includeusing namespace std class i...