noip模拟赛 gcd

题目更正:输出的a<b.

分析:这是一道数学题,范围这么大肯定是有规律的,打个表可以发现f(a,b)=k,a+b最小的a,b是斐波那契数列的第k+1项和k+2项.矩阵快速幂搞一搞就好了.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int mod = 1e9 + 7;

typedef long long ll;

ll k;
struct node
{
    ll a[3][3];
    node() { memset(a, 0, sizeof(a)); }
};

node mul(node x, node y)
{
    node p;
    for (int i = 1; i <= 2; i++)
        for (int j = 1; j <= 2; j++)
            for (int k = 1; k <= 2; k++)
                p.a[i][j] = (p.a[i][j] + x.a[i][k] * y.a[k][j] % mod) % mod;
    return p; 
}

void qpow(ll b)
{
    node x, y, z;
    x.a[1][1] = 1;
    x.a[1][2] = 0;
    y.a[1][1] = y.a[1][2] = y.a[2][1] = 1;
    y.a[2][2] = 0;
    while (b)
    {
        if (b & 1)
            x = mul(x, y);
        y = mul(y, y);
        b >>= 1;
    }
    printf("%lld %lld", x.a[1][2],x.a[1][1]);
}

int main()
{
    scanf("%lld", &k);
    if (k != 1)
        qpow(k + 1);
    else
        printf("1 1");

    return 0;
}

 

posted @ 2017-10-24 14:07  zbtrs  阅读(187)  评论(0编辑  收藏  举报