【题解】洛谷 P3938 斐波那契【20201013 CSP 模拟赛】

题目链接

题目链接

题意

第一个月有 \(1\) 对兔子,编号为 \(1\),之后每个月,年龄大于 \(1\) 的兔子会生一对新的兔子(如同斐波那契数列的模型),新生兔子按出生时间编号,出生时间相同则按双亲编号小的编号小。\(m\) 次询问 \(x\)\(y\) 的最近公共祖先。\(m\leq 3\times 10^5\)\(x,y\leq 10^{12}\)

题解

\(x\) 的父亲为 \(x\) 减去小于 \(x\) 的最大的斐波那契数。树深是 \(\log\) 级别的,于是暴力往上跳即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll getint(){
	ll ans=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		ans=ans*10+c-'0';
		c=getchar();
	}
	return ans*f;
}
ll f[62],cnt=2;
int main(){
//	freopen("t1.in","r",stdin);
//	freopen("t1.out","w",stdout);
	int m=getint();
	f[0]=f[1]=1;
	for(cnt=2;f[cnt-1]<=1e12;cnt++){
		f[cnt]=f[cnt-1]+f[cnt-2];
	}
	while(m --> 0){
		ll x=getint(),y=getint();
		int p=cnt-1;
		while(x!=y){
			(x<y)?swap(x,y),0:0;
			while(f[p]>=x)--p;
			x-=f[p];
		}
		printf("%lld\n",x);
	}
	return 0;
}

posted @ 2020-10-13 21:20  破壁人五号  阅读(105)  评论(0编辑  收藏  举报