D数树,牛客小白月赛78,思维
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
“开导!”
众所周知,树是一种特殊的图。
众所周知(二),导出子图是由该图顶点的一个子集和该图中两端均在该子集的所有边的集合组成的图。
注1:二叉树是有向图。
注2:有向图的导出子图,还是有向图。
小沙有 nnn 个节点,他需要你构造出一颗有根二叉树,使得二叉树的所有导出子图是一颗满二叉树的数目尽可能多。
请问构造出来的有根二叉树的所有导出子图是一颗满二叉树的数目最多是多少?
你能帮帮不会数/树的小沙吗?
输入描述:
第一行读入一个整数 TTT ,代表多组样例。
随后 TTT 行,每行输入一个正整数 nnn。
保证有 1≤T≤1051 \le T \le 10^51≤T≤105,1≤n≤10181 \le n \le 10^{18}1≤n≤1018。
输出描述:
对于每组样例输出一行整数代表答案。
由于答案过大,所以请输出答案对 109+710^9 + 7109+7 取模的值。
示例1
输入
复制10 1 2 3 4 5 6 7 8 9 10
10 1 2 3 4 5 6 7 8 9 10
输出
复制1 2 4 5 7 8 11 12 14 15
1 2 4 5 7 8 11 12 14 15
说明
对于 777 个节点的最优二叉树为
其 111111 个导出子图为满二叉树的有
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL n;
int fun(LL a) {
LL t = 1,ret=0;
while (t <= a) {
ret += a / t;
t *= 2;
}
return ret;
}
int main() {
int cnt;
cin >> cnt;
while (cnt--) {
cin >> n;
LL ans = 0;
LL t = 1, sum = 0,p=1;
while (sum + t <= n) {
ans = (ans + p) % mod;
sum += t;
t *= 2;
p += t;
}
if (n - sum > 0) {
ans = (ans + fun(n - sum)) % mod;
}
cout << ans << endl;
}
return 0;
}