Interesting Integers BAPC 2014 Final [ 扩展欧几里德算法 ]

14 篇文章 0 订阅
2 篇文章 0 订阅

题目链接:

I. Interesting Integers

题意概括:

Gabonacci数列类似于斐波那契数列,都满足某位的值是前两位的和

G_{I}=G_{i-1}+G_{i-2} \, ,\, i> 2

不同点在于该数列前两位 G_{1}\, ,\, G_{2} 是由我们自定义的。

现在指定一个 n , 求最小的 G_{1}=a\, ,\, G_{2}=b 组合,使 n 是该数列中的某一位。最小的定义是

b 尽可能小,同时 a\leq b\, ,不存在 b 相同,a 不同的情况。

数据范围:

2\leq n\leq 10^{9} , 测试数据不超过100组

题解思路:

当 G_{1}=a\, ,\, G_{2}=b , 我们可以列举后面的几位

G_{3}=a+b\,,\, G_{4}=a+2b\,,\, G_{5}=2a+3b\,,\, G_{6}=3a+5b\, \cdots

可以发现,每一位上的 a 与b 的系数各自都满足变形的斐波那契数列

F=1,0,1,1,2,3,5,8,13\cdots

问题简化成求解等式

 n=F\left ( i \right )a+F\left ( i+1 \right )b

由于 2\leq n\leq 10^{9} , 当数列的值达到1e9结束,因此 i\leq 45 , 只需要遍历 i 的所有情况,每种情况可以构造出一个二元一次方程

用扩展欧几里德算法求解不定方程的方法便可。传送门。

注意此题对解有限定(x = a , y = b):

  • y 要尽量小
  • \leq y 

对一个不定方程而言,x与y的值是互斥的,或者说是当一个增大时,另一个按比例减小。所以,这里实质上就是在求x、y最接近时的解。

代码:

//求x,y最接近的解,x <= y.
bool Indefinite_equation(int a, int b, int n, ll& x, ll& y) {     
    int gcd = extgcd(a, b, x, y);
    if (n % gcd) return false;
    int k = n / gcd, dx = b / gcd, dy = a / gcd;           //dx,dy分别为对应的变化值
    x *= k;
    y *= k;                                                //此为某特解
    ll cnt = (y - x) / (dx + dy);
    if (cnt < 0 && (y - x) % (dx + dy)) cnt --;            //处理x > y的情况
    x += dx * cnt;
    y -= dy * cnt;
    return true;
}

具体的证明在另外文章中有说。

这里请注意,参与计算的 x , y 应该开成 long long 型,否则在扩展欧几里德算法求特解时,会溢出。

AC代码:

#include <stdio.h>
using namespace std;
const int MAXN = 46;
typedef long long ll;

int extgcd(int a, int b, ll& x, ll& y) {
    int gcd = a;
    if (b != 0) {
        gcd = extgcd(b, a % b, y, x);
        y -= (a / b) * x;
    }
    else {
        x = 1; y = 0;
    }
    return gcd;
}

//求x,y最接近的解,x <= y.
bool Indefinite_equation(int a, int b, int n, ll& x, ll& y) {     
    int gcd = extgcd(a, b, x, y);
    if (n % gcd) return false;
    int k = n / gcd, dx = b / gcd, dy = a / gcd;           //dx,dy分别为对应的变化值
    x *= k;
    y *= k;                                                //此为某特解
    ll cnt = (y - x) / (dx + dy);
    if (cnt < 0 && (y - x) % (dx + dy)) cnt --;            //处理x > y的情况
    x += dx * cnt;
    y -= dy * cnt;
    return true;
}

int main() {
    int T;
    scanf("%d", &T);
    int f[MAXN] = {1, 0};
    for (int i = 2; i < MAXN; i++)
        f[i] = f[i - 1] +f[i - 2];
    while (T --) {
        int n;
        scanf("%d", &n);
        ll tempx, tempy, x = 0, y = 0x3f3f3f3f;
        for (int i = 0; i < MAXN - 1; i++) {
            Indefinite_equation(f[i], f[i + 1], n, tempx, tempy);
            if (tempx > 0 && tempy > 0 && tempy < y) {x = tempx; y = tempy;}
        }
        printf("%lld %lld\n", x, y);
    }
}

 

                                                  Interesting Integers

 

Undoubtedly you know of the Fibonacci numbers. Starting with F1 = 1 and F2 = 1,every next number is the sum of the two previous ones. This results in the sequence1,1,2,3,5,8,13,⋅⋅⋅.

Now let us consider more generally sequences that obey the same recursion relationG_{I}=G_{i-1}+G_{i-2} \,, for\, i> 2

but start with two numbers G_{1}\leq G_{2} of our own choice. We shall call these Gabonacci sequences. For example, if one uses G_{1} = 1 and G_{2} = 3, one gets what are known as the Lucas numbers: 1, 3, 4, 7, 11, 18, 29, ⋅ ⋅ ⋅ . These numbers are – apart from 1 and 3 – different from the Fibonacci numbers.

By choosing the first two numbers appropriately, you can get any number you like to appear in the Gabonacci sequence. For example, the number n appears in the sequence that starts with 1 and n − 1, but that is a bit lame. It would be more fun to start with numbers that are as small as possible, would you not agree?

Input Format

On the first line one positive number: the number of test cases, at most 100. After that per test case:

one line with a single integer n (2\leq n\leq 10^{9}): the number to appear in the sequence.

Output Format

Per test case: one line with two integers a and b (0<a≤b), such that,for G_{1} =a and G_{2} =b, G_{k}= n for some k. These numbers should be the smallest possible, i.e., there should be no numbers a′ and b′ with the same property, for which b′ < b, or for which b′ = b and a′ < a.

样例输⼊

5
89
123
1000
1573655
842831057

样例输出

1 1
1 3
2 10
985 1971 
2 7

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值