qoj10869 Half-Sequence
思路
傻逼。
前几项比较特殊,需要特判,之后的项可以简单的通过前面的项推出来。
当 \(fib_{i}>10^{18}\) 时,容易发现序列变为 \(i+1,-1,i+3,-1,\cdots\) 交错,预处理即可。
注意特判 \(n\) 为斐波那契数列中的数的结果。
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll fib[105]={0,1,2},T,n;
map<ll,ll> ans,bs;
void init(){
ans[1]=1,ans[2]=2,ans[3]=3,ans[4]=6,ans[5]=13;
ans[6]=5,ans[7]=9,ans[8]=377,ans[9]=21,ans[10]=11;
ans[377]=34,ans[34]=-1,ans[9227465]=-1;
}
void sol(){
for(ll i=1;i<=88;i++){
if(ans[i]==0){
ll j=i+1;
while(ans[j]!=0) j++;
ans[i]=j,ans[j]=fib[i];
}
ll j=i;
if(ans[j]==-1) continue;
while(ans[ans[j]]==0){
if(j>86){
ans[ans[j]]=-1;
break;
}
ans[ans[j]]=fib[j];
j=ans[j];
}
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
init();
for(int i=3;i<=86;i++)
fib[i]=fib[i-1]+fib[i-2];
sol();
// for(pair<ll,ll> v:ans) cout<<v.first<<" "<<v.second<<endl;
for(int i=12;i<=86;i++)
bs[i]=((fib[i]-fib[i-1]+bs[i-1])%2==0?1:0);
// cout<<i<<":"<<fib[i]<<","<<bs[i]<<endl;
cin>>T;
while(T--){
cin>>n;
if(ans[n]!=0) cout<<ans[n]<<endl;
else if(n<=90) cout<<(ans[n]==0?-1:ans[n])<<endl;
else{
ll lst=0;
for(int i=3;i<=86;i++)
if(fib[i]<n&&(i==86||fib[i+1]>n)){
lst=i;
break;
}
cout<<((n-fib[lst]+bs[lst])%2==1?-1:ans[n+1]!=0?n+2:n+1)<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号