这是一道好题。
首先,我们先将兔子分组。
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪1234,56,7,89,10,11,12,13
就是按出生时间分组,记
ri,j
表示第
i
月第
我们易得
*
ri,1=febi+1
(
i>1
)
*
fk=k−maxfebi<ki=1febi
证明:
很显然啊,不然你以为斐波那契数列哪来的
式子意思是:当前数减去比它小的最大的斐波那契数。
我们需要先证明:
- fri,k=k
证明:这题就是这尿性啊,看图就明白了。
- 在一双兔子出生前,有 febk 只兔子
证明:感觉没好说的啊,斐波那契数列性质
然后结合那两个式子(相加),就是了啊
(雾)。
然后,就是跑以下LCA就好了。
分析一下复杂度吧。
期望: O(mlog2max{ba)
我们可以得出:
k2<maxfebi<ki=1febi
设 j 是满足右式的
i 由性质得
- febj>febj−1
- febj+1=febj−1+febj<2febj
若 k>2febj
那么我们会取到 j+1
所以每次会砍掉至少一半。
代码:
#define fr(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
#define fd(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
int read()
{
int r=0,t=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
t=-1;
else
t=1;
c=getchar();
}
while(c>='0'&&c<='9')
{
r=(r<<3)+(r<<1)+(c^48);
c=getchar();
}
return r*t;
}
long long f[100];
long long del(long long k)
{
int l=1,r=81;
while(l<r)
{
int mid=(l+r)>>1;
if(f[mid]<k)
l=mid+1;
else
r=mid;
}
return k-f[l-1];
}
int t;
int main()
{
t=read();
f[0]=1;
f[1]=1;
fr(i,2,80)
f[i]=f[i-1]+f[i-2];
while(t--)
{
long long a,b;
scanf("%lld%lld",&a,&b);
while(a!=b)
{
if(a>b)
a=del(a);
else
b=del(b);
// printf("%lld %lld\n",a,b);
}
printf("%lld\n",a);
}
return 0;
}