优 秀 的 树

题目链接:优秀的树

  • 时间限制:C/C++ 2000MS,其他语言 4000MS
  • 内存限制:C/C++ 256MB,其他语言 512MB

给定一棵树,其所有边权重均为 1,定义 f ( u ) = ∑ v d i s ( u , v ) f(u)=\sum_{v} dis(u,v) f(u)=vdis(u,v) v v v 表示树上的所有结点, d i s ( u , v ) dis(u,v) dis(u,v) 表示结点 u u u v v v 的简单路径的长度。

一棵树被称为“优秀”,当且仅当存在两个结点 u u u v v v 满足 f ( u ) − f ( v ) = x f(u)-f(v)=x f(u)f(v)=x

给定 x x x,求满足 “存在两个结点 u u u v v v 满足 f ( u ) − f ( v ) = x f(u)-f(v)=x f(u)f(v)=x” 成立的树最少有多少个结点。

输入描述

输入有多组测试用例,第一行包含一个整数 t ( 1 ≤ t ≤ 1 0 5 ) t(1≤t≤10^5) t(1t105),表示接下来有 t t t 组测试用例。

每一个测试用例包含一个整数 x ( 1 ≤ x ≤ 1 0 18 ) x(1≤x≤10^{18}) x(1x1018)

输出描述

对每一个测试用例,输出一个整数,表示能满足条件被称为 “优秀” 的树结点最少为多少。

可以证明答案总是存在的。

示例

  • 输入

    3
    2
    3
    114514

  • 输出**

    4
    5
    678

提示

  • 1 ≤ t ≤ 1 0 5 1≤t≤10^5 1t105
  • 1 ≤ x ≤ 1 0 18 1≤x≤10^{18} 1x1018

理论背景

  1. 树的定义

    • 在树结构中,任意两个节点之间的路径是唯一的,且边的权重为1。
  2. 函数 f(u)

    • f(u) 表示从节点 u 到树中所有其他节点的距离之和,即: f ( u ) = ∑ v ∈ tree dis ( u , v ) f(u) = \sum_{v \in \text{tree}} \text{dis}(u, v) f(u)=vtreedis(u,v)
    • 这里的 dis(u, v) 是节点 u 和节点 v 之间的简单路径长度。
  3. 差值 f(u) - f(v)

    • 我们关注的是 f(u) - f(v) 的值,这个值的计算依赖于 uv 之间的关系。
    • 通过选择不同的节点 uv,我们可以得到不同的 f(u) - f(v) 的值。

公式推导

  1. 完全平方数的情况

    • x 是完全平方数,即 k * k = x,那么 f(u) - f(v) 的差值可以通过节点的深度和数量的关系来推导。
    • 在这种情况下,输出 k / 2 + 1 是因为我们可以选择一棵特定结构的树(如完全二叉树)来满足条件。
  2. 偶数与范围条件

    • xk * (k + 1) 范围内且 x 为偶数时,我们可以构造一棵树,使得 f(u) - f(v) 的值能够精确到这个范围,因此输出 k / 2 + 2
  3. 其他情况

    • 对于其他情况,输出 k / 2 + 3 是为了确保无论 x 的值如何变化,我们总能找到一棵树使得 f(u) - f(v) = x 成立。

总结

这些公式的选择是基于树的结构性质、节点之间的关系以及如何通过不同的树形结构来满足 f(u) - f(v) = x 的条件。通过数学推导和对树的性质的理解,我们得出了这些公式。


AC代码:

#include<bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		long long x; 
		cin >> x;
		long long k = sqrtl(x); // 计算x的平方根k
		if(k * k == x) 
			cout << k << 1 + 1 << endl; 
		else 
			if(x <= k * (k + 1) && !(x & 1))  // 判断x是否在k * (k + 1)范围内且为偶数
				cout << k << 1 + 2 << endl;	
			else 
				cout << k << 1 + 3 << endl;
	}
	return 0;
}
  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值