挺有意思的一道题
容易发现k越大甲越容易赢,那么a[i]表示最小的可以使甲赢的数,则a[i-a[i]]>=2a[i],可以打表,然后发现这个表与斐波那契数列有关。
众所周知,任何自然数都可以被唯一拆分成若干不同斐波那契数的和,即可以化为斐波那契进制,然后最小的斐波那契数(即斐波那契进制下的lowbit)即为a[i]
然后a数组即k本质上不同的数只有至多90个(斐波那契数在1e18以内的个数),然后s[i][j]表示前fib[i]项中fib[j]出现次数,这个很容易做出来。
然后询问答案难度就不大了……
#include<bits/stdc++.h> using namespace std; int p,T; long long n,k,ans,f[100],s[100][100]; int main() { f[0]=1,f[1]=1; for(int i=1;i<=90;i++) { f[i+1]=f[i]+f[i-1],s[i][i]=1; for(int j=1;j<=i;j++)s[i+1][j]=s[i-1][j]+s[i][j]-(j==i-1); } for(int i=1;i<=90;i++)for(int j=1;j<=90;j++)s[i][j]+=s[i][j-1]; scanf("%d",&T); while(T--) { ans=p=0; scanf("%lld%lld",&k,&n); while(f[p+1]<=k)p++; for(int i=90;i;i--)if(n>f[i])n-=f[i],ans+=s[i][p]; printf("%lld ",ans); } }