[AGC015F] Kenus the Ancient Greek

· · 题解

tag:数论,构造(?)

题意

给定 X,Y,设 g(x,y) 为 对 x,y 用辗转相除法求gcd需要的步数。求 gcd(x,y),\ x\le X,\ y\le Y 的最大值,和能取到最大值的 (x,y) 的对数。

Q\le300000,\ X,Y\le10^{18},\ mod=10^9+7

题解

最大值很好求,考虑倒推,就是让每一步的两个数尽量小,所以让“辗转相除法”变为“辗转相减”就行了。(0,1)\to(1,2)\to(2,3)\to(3,5),发现这个就是斐波那契数列,所以找到最大的 i,\ fib(i)\le X, fib(i+1)\le Y 就行了。

考虑求对数。由于 g(a,b)=g(a,b+ka),所以不用考虑完所有情况,只需要考虑 g(a,b)=ans,\ a<b<2a,然后可以直接用除法计算出贡献。

接下来考虑如何找出这些 (a,b)

把倒推过程画出来。

对于 ans=3 的情况,只有 (2,3)(3,4),倒推路径分别为:

0\to1\to2\to3 0\to1\to3\to4

对于 ans=4 的情况,首先可以在 ans=3 的基础上往后扩展为 0\to1\to2\to3\to50\to1\to3\to4\to7。其次,我们还可以把第一条路径的 “3” 改大一点点,形成一条新的倒推路径:

0\to1\to2\to5\to7

但是只能延伸出一条新的路径,因为把第一条路径的 “3” 改为 “7” 后,

0\to1\to2\to7\to9

此时答案(指 \max\{g(a,b)\})就为 5 了。因为既然 (7,9) 存在,那么 (5,8)(对应路径 0\to1\to2\to3\to5\to8) 也存在。

所以推出 ans=4 时有 (3,5)(4,7)(5,7)

那么这个规律能否拓展到一般情况呢?考虑从 ans=k 推出 ans=k+1

首先对于每对 ans=k(a,b),显然可以推出一对 ans=k+1(b,a+b)

然后类似于上面,考虑将最小的那条路径的结尾改大一点点,延伸出一条分支。比如 ans=k 时,第一条路径最后部分为:

\cdots\to a\to b

那么把 b 改为 a+b,可以延伸出一条 ans=k+1 的倒推路径:

\cdots\to a\to a+b\to 2a+b

这样会让值域扩充到 (a+b,2a+b),所以我们还要考虑 \max\{g(x,y)\} 会不会变大。实际上只用考虑最小的那条倒推路径,他的下一个元素是 a+2b,而2a+b<a+2b。也就是说这条路径的加入,不会导致第一条路径变长,即不会让 ans 变大。

那如果将最小的那条路径结尾再改大一点点呢,如果把 b 改为 2a+b,延伸出另一条路径:

\cdots\to a\to 2a+b\to 3a+b

此时值域被扩充到了 (2a+b,3a+b),而由于第一条路径就是斐波那契数列,所以有 b<2a,所以 3a+b>a+2b。也就是说如果这条路径加入了,那么第一条路径还可以加入一个元素,即 \max\{g(x,y)\} 会变大,所以这条路径是不合法的。

而对于 \max\{g(x,y)\}=k 的其他倒推路径,就更不可能延伸出新的路径了(证明类似)。

所以 ans=k 时相对于 ans=k-1 时,只会多出一对 (fib(k+1),fib(k+1)+fib(k-1))

所以得到构造方法:

然后求解对数就枚举每一对元素直接计算即可。

while(ans[res+1][1].first<=x and ans[res+1][1].second<=y) res++;
for(register int i=1; i<=res; i++){
    if(ans[res][i].first<=x and ans[res][i].second<=y) sum += (y-ans[res][i].second)/ans[res][i].first+1;
    if(ans[res][i].second<=x) sum += (x-ans[res][i].second)/ans[res][i].first+1;
    sum %= MOD;
}

注意特判一下 ans=1 时,每一对 (i,i) 都是合法的,所以加上 min(X,Y)

完整代码