優秀的樹 - 題解(數學)

Jerrycyx發表於2024-08-02

優秀的樹

時間限制: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;
}

相關文章