51 nod 1350 斐波那契表示

时间:2024-12-28 08:33:26
每一个正整数都可以表示为若干个斐波那契数的和,一个整数可能存在多种不同的表示方法,例如:14 = 13 + 1 = 8 + 5 + 1,其中13 + 1是最短的表示(只用了2个斐波那契数)。定义F(n) = n的最短表示中的数字个数,F(14) = 2,F(100) = 3(100 = 3 + 8 + 89),F(16) = 2(16 = 8 + 8 = 13 + 3)。定义G(n) = F(1) + F(2) + F(3) + ...... F(n),G(6) = 1 + 1 + 1 + 2 + 1 + 2 = 8。给出若干个数字n,求对应的G(n)。
Input
第1行:一个数T,表示后面用作输入测试的数的数量(1 <= T <= 50000)。
第2 - T + 1行:每行1个数n(1 <= n <= 10^17)。
Output
输出共T行:对应每组数据G(n)的值。
Input示例
3
1
3
6
Output示例
1
3
8
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a)) int t;
ll n;
ll f[],A[];
void init()
{
A[]=A[]=;
f[]=f[]=;
F(i,,)
{
f[i]=f[i-]+f[i-];
A[i]=A[i-]+A[i-]+f[i-];
}
} ll solve(int id,ll num)
{
if(f[id]==num) return A[id];
if(f[id-]>=num) return solve(id-,num);
return A[id-]+num-f[id-]+solve(id-,num-f[id-]);
} int main()
{
init();
for(scanf("%d",&t);t--;)
{
scanf("%lld",&n);
ll sum=,ans=;
int id=;
while(sum+f[id+]<n) sum+=f[++id];
F(i,,id) ans+=A[i];
ans+=solve(id+,n-sum);
printf("%lld\n",ans);
}
return ;
}

不是太明白,贴了一下别人的代码供以后学习

原文链接