P120练习赛
题目目录
第一题 交互题
题意
一句话题意:求把$n$拆成一些不同的斐波那契数之和的方案数。
$n\leq 10^{18}$。
题解
此题在洛谷上有原题。若想看详细题解,请转到这里。
我们可以把$n$贪心拆为几个斐波那契数之和,然后对于每一个数,我们$dp_{i0}$和$dp_{i1}$表示$1-i$的数中$i$取或不取所能得到的方案数,然后答案就是$dp_{n0}+dp_{n1}$了。
附上代码:
#include <bits/stdc++.h> #pragma GCC optimize("Ofast", "stack-protector-explicit") using namespace std; #define int long long int rd() { int ret=0;char ch; while(!isdigit(ch=getchar())); ret=ch-'0';while(isdigit(ch=getchar()))ret=ret*10+ch-'0'; return ret; } void wd(int x) { printf("%lld\n",x); } int F[87]; int dp[87][2]; int T,n; vector<int> A; inline int R(int n) { A.clear(); for (int i=86; i; i--) if (n >= F[i]) { A.push_back(i); n -= F[i]; } sort(A.begin(), A.end()); dp[0][0] = (A[0]-1)/2; dp[0][1] = 1; for (int i=1; i<A.size(); i++) { dp[i][1] = dp[i-1][0] + dp[i-1][1]; dp[i][0] = dp[i-1][1] * ((A[i]-A[i-1]-1)/2) + dp[i-1][0] * ((A[i]-A[i-1])/2); } return dp[A.size()-1][0] + dp[A.size()-1][1]; } signed main() { F[1] = 1; F[2] = 2; for (int i=3; i<=86; i++) F[i] = F[i-1] + F[i-2]; T = rd(); while (T--) { n = rd(); wd(R(n)); } return 0; }
第三题 传统题(提交答案)
题意
一句话题意:每组数据给你小样例和大输入,让你求大输出。(都是数据结构的操作)