给出Fibonacci的第i项和第j项。求第n项。
Input
The input contains five integers in the following order: i, Fi, j,Fj, n.
−1000 ≤ i, j, n ≤ 1000, i ≠ j,
−2·109 ≤ Fk ≤ 2·109 (k = min(i, j, n), …, max(i, j, n)).
Output
The output consists of a single integer, which is the value of Fn.
Sample
Input : 3 5 -1 4 5Ouput : 12 答案计算:f[3]=f[2]+f[1]=2f[1]+f[0]=3f[0]+f[-1],即5=3f[0]+4, 得f[0]=-1f[5]=f[4]+f[3]=2f[3]+f[2]=10+f[1]+f[0]=10+2f[0]+f[-1]=10-2+4=12
1)求f[i+1]
斐波那契数列是相邻两项的关系,ij不相邻,要先求出i+1项。1)方程计算列出fi,fj,f(i+1)的关系 : fj = a[j-i-1]f[i+1] + a[j-i-2]f[i]其中,a数列满足a[i]=a[i-1]+a[i-2],也是一个斐波那契数列,这里j-i>0,且i j已知,所以可以求得。这种方法求出a[i+1]复杂度应该是2000以内的,不知道为什么超时了。2)二分求解f的范围是[-2*10^9, 2*10^9] ,而斐波那契数列是单调的,从最大最小数开始枚举,从f[i]和f[i+1]递推求j项,和f[j]对比,调整枚举空间。二分是log(10^9)很快。像平时玩猜数字游戏一样。10^9里找一个数字一会儿就找出来了。
2)求f[n]
从f[i]和f[i+1]递推求
二分代码:
const long long MAXN = 2000000000; long long i,fi,j,fj,n; void swap(long long &i,long long &j) { i=i+j; j=i-j; i=i-j; } int main() { cin >> i >> fi >> j >> fj >> n; if(i>j) {swap(i,j);swap(fi,fj);} // cal f[i+1] long long l=-MAXN, r=MAXN, mid; long long ti=fi, tj=mid, t; while (l+1<r){ mid = (l+r)/2; ti=fi; tj=mid; for (int k=i+2; k<=j; ++k){ t=ti+tj; ti=tj; tj=t; if(t>MAXN*2 ||t<-MAXN*2) break; } if(tj>=fj) r = mid; else l=mid; } ti=fi; tj=r; if(n>i){ for(int k=i+2;k<=n;++k){ t=ti+tj; ti=tj; tj=t; } cout << tj << endl; } else { for(int k=i-1; k>=n; ++k){ t=tj-ti; tj=ti; ti=t; } cout << ti << endl; } cin >> ti; return 0; }
时间: 2024-11-11 16:09:49