Interesting Integers BAPC 2014 Final [ 擴展歐幾里德算法 ]

題目鏈接:

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章