您的位置:首页 > 产品设计 > UI/UE

ural 1133 Fibonacci Sequence 二分枚举

2015-10-15 13:04 579 查看
给出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 5
Ouput : 12

答案计算:
f[3]=f[2]+f[1]=2f[1]+f[0]=3f[0]+f[-1],
即5=3f[0]+4, 得f[0]=-1
f[5]=f[4]+f[3]=2f[3]+f[2]=10+f[1]+f[0]=10+2f[0]+f[-1]=10-2+4=12

[b]1)求f[i+1][/b]

斐波那契数列是相邻两项的关系,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里找一个数字一会儿就找出来了。

[b]2)求f
[/b]

 从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;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: