Codeforces Round #257 (Div. 2)B 矩阵快速幂

B. Jzzhu and Sequences

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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).

Sample test(s)

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 + f3 = f2

f3 = f2 - f1

f3 = 1 * f2 + -1 * f1

f2 = 1 * f2 +  0 * f1

所以矩阵就是

1, -1

1,  0

然后就是取模运算和负数处理了。负数取模会返回负数。因为我是快速幂的写法,最后返回的数一定是在(-Mod, Mod)之间的,所以直接加上一个Mod,然后再取一次模就好了。

代码示例

/******************************************************************************
*       COPYRIGHT NOTICE
*       Copyright (c) 2014 All rights reserved
*       ----Stay Hungry Stay Foolish----
*
* @author		:Shen
* @name         :B
* @file         :G:\My Source Code\【ACM】比赛\0719 - CF\B.cpp
* @date         :2014/07/19 20:57
* @algorithm    :Matrix Fast Power Method
******************************************************************************/

#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long int64;

const int MAXN = 2;
const int MAXM = 2;
const int Mod = 1000000007;

struct Matrax{
    int n, m;
    int64 mat[MAXN][MAXM];
    Matrax(): n(-1), m(-1){}
    Matrax(int _n, int _m): n(_n), m(_m){
        memset(mat, 0, sizeof(mat));
    }
    void Unit(int _s){
        n = _s; m = _s;
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                mat[i][j] = (i == j)? 1: 0;
            }
        }
    }
    void print(){
        printf("n = %d, m =  %d\n", n, m);
        for (int i = 0; i < n; i++){
            for (int j = 0; j < m; j++)
                printf("%8d", mat[i][j]);
            printf("\n");
        }
    }
};

Matrax add_mod(const Matrax& a,const Matrax& b,const int64 mod){
    Matrax ans(a.n, a.m);
    for (int i = 0; i < a.n; i++){
        for (int j = 0; j < a.m; j++){
            ans.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % mod;
        }
    }
    return ans;
}

Matrax mul(const Matrax& a,const Matrax& b){
    Matrax ans(a.n, b.m);
    for (int i = 0; i < a.n; i++){
        for (int j = 0; j < b.m; j++){
            int64 tmp = 0;
            for (int k = 0; k < a.m; k++){
                tmp += a.mat[i][k] * b.mat[k][j];
            }
            ans.mat[i][j] = tmp;
        }
    }
    return ans;
}

Matrax mul_mod(const Matrax& a, const Matrax& b, const int mod){
    Matrax ans(a.n, b.m);
    for (int i = 0; i < a.n; i++){
        for (int j = 0; j < b.m; j++){
            int64 tmp = 0;
            for (int k = 0; k < a.m; k++){
                tmp += (a.mat[i][k] * b.mat[k][j]) % mod;
            }
            ans.mat[i][j] = tmp % mod;
        }
    }
    return ans;
}

Matrax pow_mod(const Matrax& a, int64 k, const int mod){
    Matrax p(a.n, a.m), ans(a.n, a.m);
    p = a; ans.Unit(a.n);
    if (k==0) return ans;
    else if (k==1) return a;
    else {
        while (k){
            if (k & 1){
                ans = mul_mod(ans, p, mod);
                k--;
            }
            else {
                k /= 2;
                p = mul_mod(p, p, mod);
            }
        }
        return ans;
    }
}

int64 x, y, n, res;

void solve(){
    cin >> x >> y >> n;
    if (n == 1) res = x;
    else if (n == 2) res = y;
    else
    {
        Matrax ans(2, 1);

        //tmp = cef ^ (n - 2);
        //ans = tmp * beg;
        //res = ans.mat[0][0];

        Matrax cef(2, 2);
        cef.mat[0][0] = 1; cef.mat[0][1] = -1;
        cef.mat[1][0] = 1; cef.mat[1][1] =  0;
        //cef.print();

        Matrax beg(2, 1);
        beg.mat[0][0] = y; beg.mat[1][0] = x;

        Matrax tmp(2, 2);
        tmp = pow_mod(cef, n - 2, Mod);
        //tmp.print();

        ans = mul_mod(tmp, beg, Mod);
        //ans.print();
        res = ans.mat[0][0];
    }
    if (res < 0) res += Mod;
    cout << res << endl;
}

int main()
{
    solve();
    return 0;
}
时间: 2024-12-28 14:00:11

Codeforces Round #257 (Div. 2)B 矩阵快速幂的相关文章

Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\end{aligned} \] 思路 我们通过迭代发现\(f_n\)其实就是由\(c^{x_1},f_1^{x_2},f_2^{x_3},f_3^{x_4}\)相乘得到,因此我们可以分别用矩阵快速幂求出\(x_1,x_2,x_3,x_4\),最后用快速幂求得答案. 对\(f_1,f_2,f_3\): \[ \begin{aligned} (x_n&&

Codeforces Round #257 (Div. 2)

A.Jzzhu and Children 计算每个人会出现的轮次数,取最后一个且轮次数最大的,注意是用a[i]-1 % m,倒着扫一遍就行了 #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int maxn = 100+10; int n, m; int a[maxn]; int main() { #ifdef LOCAL freopen("

Codeforces Round #257 (Div. 2) E题:Jzzhu and Apples 模拟

E. Jzzhu and Apples time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Jzzhu has picked n apples from his big apple tree. All the apples are numbered from 1 to n. Now he wants to sell them to

Codeforces Round #257 (Div. 2) A/B/C/D

前三题早就写好了,一直在纠结D A. Jzzhu and Children 题意:就是简单的模拟,给排成一队的孩子分发糖果,每个孩子有至少要得到的糖果数. 然后每次给队头的孩子分发m个糖果,如果他已经得到了足够的糖果(大于等于他想得到的 最少糖果数)那么他就出队,否则他就去队尾.问最后一个孩子的编号. 算法:队列模拟,水题~ #include<cstdio> #include<iostream> #include<cstring> #include<queue&g

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities[最短路] 题目链接:点击打开 题目大意: 在一个国家中有n个城市(城市编号1~n),m条公路和k条铁路,编号为1的城市为首都,为了节约,不需要的铁路需要关闭,问在保证首都到其余所有城市的最短路不变的条件下,最多有多少条铁路是不需要的. 解法: 这个题比较麻烦,保证首都到其余城市的最短路不变,要求出最多有多少条铁路是不需要的,那肯定是从最短路的代码上下手了,我们首先考虑dijkstra算法

Codeforces Round #257(Div.2) D Jzzhu and Cities --SPFA

题意:n个城市,中间有m条道路(双向),再给出k条铁路,铁路直接从点1到点v,现在要拆掉一些铁路,在保证不影响每个点的最短距离(距离1)不变的情况下,问最多能删除多少条铁路 分析:先求一次最短路,铁路的权值大于该点最短距离的显然可以删去,否则将该条边加入图中,再求最短路,记录每个点的前一个点,然后又枚举铁路,已经删去的就不用处理了,如果铁路权值大于该点最短距离又可以删去,权值相等时,该点的前一个点如果不为1,则这个点可以由其他路到达,这条铁路又可以删去. 由于本题中边比较多,最多可以有8x10^

Codeforces Round #257 (Div. 2/A)/Codeforces450A_Jzzhu and Children

解题报告 没什么好说的,大于m的往后面放,,,re了一次,,, #include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; struct node { int x,cd; }num[1000000]; int main() { int n,m,c; cin>>n>>m; int i; for(i=0;i&l

Codeforces Round #257 (Div. 2/B)/Codeforces450B_Jzzhu and Sequences

B解题报告 算是规律题吧,,,x y z -x -y -z 注意的是如果数是小于0,要先对负数求模再加模再求模,不能直接加mod,可能还是负数 给我的戳代码跪了,,, #include <iostream> #include <cstring> #include <cstdio> using namespace std; long long x,y,z; long long n; int main() { cin>>x>>y; cin>&g

Codeforces Round #257 (Div. 1) (Codeforces 449B)

题意:给力一张无向图,有一些边是正常道路,有一些边是铁路,问最多能删除几条铁路使得所有点到首都(编号为1)的最短路长度不变. 思路:求不能删除的铁路数,总数减掉就是答案.先求出首都到所有点的最短路,求完最短路后,枚举除首都外所有点,如果这个点被更新的边中只有铁路,那么就有一条铁路不能删除. 注意:这里求最短路一开始用SPFA在第45个点TLE,最后换成带堆优化Dijkstra #include<cstring> #include<algorithm> #include<cst