NC15979 小q的数列

题目

题目描述

小q最近迷上了各种好玩的数列,这天,他发现了一个有趣的数列,其递推公式如下:

f[i]={0,i=01,i=1f[i/2]+f[i%2],i2

现在,他想考考你,问:给你一个 n (n<1018),代表数列的第 n 项,你能不能马上说出 f[n] 的值是多少,以及 f[n] 所代表的值第一次出现在数列的哪一项中?

输入描述

输入第一行一个 t
随后 t 行,每行一个数 n ,代表你需要求数列的第 n 项,和相应的 n
(t<4105)

输出描述

输出每行两个正整数
f[n]n ,以空格分隔

示例1

输入

2
0
1

输出

0 0
1 1

题解

知识点:递归,数学。

按公式递归求值不难,接下来证明求最小 n

若把 n 看成二进制,公式可理解为 f[n>>1]+f[n&1] ,即对于每位如果为 1 则加 1 ,因此 f[n] 的结果是 n 二进制位为 1 的数量。那么一个数 nf[n]f[n] 相同而且要最小,只要把 f[n]1 从低位到高位排列,就能构造 n。所以,n=2f[n]1

时间复杂度 O(logn)

空间复杂度 O(1)

代码

#include <bits/stdc++.h>
using namespace std;
int f(long long n) {
if (n == 0 || n == 1) return n;
return f(n / 2) + f(n % 2);
}
int main() {
int t;
cin >> t;
while (t--) {
long long n;
cin >> n;
int ans = f(n);
cout << ans << ' ' << ((1LL << ans) - 1) << '\n';
}
return 0;
}
posted @   空白菌  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示