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;
}
posted @ 2025-09-04 21:09  WuMin4  阅读(19)  评论(0)    收藏  举报