难度:普及/提高-
题目背景
翻译自 ROIR 2023 D1T2。
斐波那契数指斐波那契数列(f0=1,f1=1,fi=fi−2+fi−1)中出现的数。
题目描述
给定一个自然数 n,求出将其表示为大于 1 的斐波那契数的乘积的方式数量。
输入格式
第一行一个数 t,表示数据组数。
接下来 t 行,每行输入一个数 n。
输出格式
对于每组测试数据,输出一个数表示答案。
输入输出样例
输入 #1
5 2 7 8 40 64
输出 #1
1 0 2 2 3
说明/提示
样例解释:
- 2=2。
- 7 无法被表示为斐波那契乘积。
- 8=8=2×2×2。
- 40=5×8=2×2×2×5。
- 64=8×8=2×2×2×8=2×2×2×2×2×2。
本题使用捆绑测试。
子任务编号 | 分值 | 2≤�≤2≤n≤ |
---|---|---|
1 | 15 | 100 |
2 | 17 | 10^5 |
3 | 9 | n 是 2 的整数次幂 |
4 | 38 | 10^9 |
5 | 21 | 10^18 |
对于所有数据,1≤t≤50,2≤n≤101^8。
思路
使用dfs搜索表示为大于 1 的斐波那契数的乘积的方式数量。
完整代码
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 1e18, M = 1e6 + 6;
typedef long long ll;
long long t,len,f[M];
int dfs(long long n, long long id) {
if (n == 1) return 1;
if (id == 1) return 0;
while (n < f[id]) id--;
ll ans = 0;
if (n % f[id] == 0) ans += dfs(n / f[id], id);
return ans + dfs(n, id - 1);
}
int main() {
cin>>t;
//freopen("a.in","r",stdin);
f[0]=1, f[1]=1;
len=1;
while (true) {
f[len+1]=f[len]+f[len-1];
len++;
if(f[len]>N) break;
}
len--;
while (t--) {
long long n;
cin>>n;
//freopen("b.in","r",stdin);
cout<<dfs(n, len)<<endl;
//freopen("c.out","w",stdout);
}
return 0;
}