Jzzhu and Sequences CodeForces - 450B(矩阵快速幂)

本文解析了CodeForces-450B题目,介绍了一种特殊的序列,通过递推公式f1=x,f2=y,对所有i(i≥2),fi=fi−1+fi+1进行分析。利用矩阵快速幂方法,解决了求fn模10^9+7的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Jzzhu and Sequences CodeForces - 450B

Jzzhu has invented a kind of sequences, they meet the following property:

这里写图片描述
You are given x and y, please calculate fn modulo 1000000007 (109 + 7).
Input

The first line contains two integers x and y (|x|, |y| ≤ 109). The second line contains a single integer n (1 ≤ n ≤ 2·109).

Output

Output a single integer representing fn modulo 1000000007 (109 + 7).

Examples
Input

2 3
3

Output

1

Input

0 -1
2

Output

1000000006

Note

In the first sample, f2 = f1 + f3, 3 = 2 + f3, f3 = 1.

In the second sample, f2 =  - 1;  - 1 modulo (109 + 7) equals (109 + 6).
题意:

给定递推式

f1=x,f2=y,i(i2)fi=fi1+fi+1f1=x,f2=y,∀i(i≥2)fi=fi−1+fi+1
分析:

我们可以转化递推式

fi+1=fifi1fi+1=fi−fi−1

即:

fi=fi1fi2fi=fi−1−fi−2

因此可以得到关系矩阵

对于n2n≥2

(fnfn1)=(1    11        0)n2(yx)(41)(41)(fnfn−1)=(1    −11        0)n−2(yx)

注意步步取模
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const ll mod = 1e9+7;
ll x,y,n;
struct Matrix{
    ll mat[3][3];
    Matrix operator * (const Matrix &b)const{
        Matrix ans;
        for(int i = 0; i < 2; i++){
            for(int j = 0; j < 2; j++){
                ans.mat[i][j] = 0;
                for(int k = 0; k < 2; k++){
                    ans.mat[i][j] = (ans.mat[i][j] + mat[i][k] * b.mat[k][j] % mod + mod) % mod;
                }
            }
        }
        return ans;
    }
};
Matrix q_pow(Matrix a,ll b){
    Matrix ans;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i = 0; i < 2; i++){
        ans.mat[i][i] = 1;
    }
    while(b){
        if(b & 1)
            ans = ans * a;
        b >>= 1;
        a = a * a;
    }
    return ans;
}
int main(){
    scanf("%lld%lld",&x,&y);
    scanf("%lld",&n);
    if(n == 1){
        printf("%lld\n",(x % mod + mod) % mod);
        return 0;
    }
    if(n == 2){
        printf("%lld\n",(y % mod + mod) % mod);
        return 0;
    }
    Matrix ans;
    ans.mat[0][0] = 1;
    ans.mat[0][1] = -1;
    ans.mat[1][0] = 1;
    ans.mat[1][1] = 0;
    ans = q_pow(ans,n-2);
    ll ret = ((ans.mat[0][0] * y % mod + ans.mat[0][1] * x % mod) % mod + mod) % mod;
    printf("%lld\n",ret);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值