優秀的樹
時間限制:C/C++ 2000MS,其他語言 4000MS
記憶體限制:C/C++ 256MB,其他語言 512MB描述
給定一棵樹,其所有邊權重均為 \(1\),定義 \(f(u)=Σ_v dis(u,v)\),v 表示樹上的所有結點,\(dis(u,v)\) 表示結點 \(u\) 和 \(v\) 的簡單路徑的長度。
一棵樹被稱為“優秀”,當且僅當存在兩個結點 \(u\) 和 \(v\) 滿足 \(f(u)−f(v)=x\)。
給定 \(x\),求滿足 “存在兩個結點 \(u\) 和 \(v\) 滿足 \(f(u)−f(v)=x\)” 成立的樹最少有多少個結點。輸入描述
輸入有多組測試用例,第一行包含一個整數 \(t(1≤t≤10^5\)) ,表示接下來有 \(t\) 組測試用例。
每一個測試用例包含一個整數 \(x(1≤x≤10^{18}\))。輸出描述
對每一個測試用例,輸出一個整數,表示能滿足條件被稱為 “優秀” 的樹結點最少為多少。
可以證明答案總是存在的。用例輸入 1
3 2 3 114514
用例輸出 1
4 5 678
提示
\(1≤t≤10^5\)
\(1≤x≤10^18\)
程式碼
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int T; scanf("%d",&T);
while(T--)
{
long long x; scanf("%lld",&x);
long long k=sqrtl(x);
if(k*k==x) printf("%lld\n",(k<<1)+1);
else if(x<=k*(k+1) && !(x&1)) printf("%lld\n",(k<<1)+2);
else printf("%lld\n",(k<<1)+3);
}
return 0;
}