数学 找规律 Jzzhu and Sequences

A - Jzzhu and Sequences

 
 
 

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

Example
Input
2 3
3
Output
1
Input
0 -1
2
Output
1000000006
Note

In the first sample, f2 = f1 + f33 = 2 + f3f3 = 1.

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

第一次用矩阵快速幂 做不出来 可能是因为N太大了

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 50000
#define N 21
#define MOD 1000000007
#define INF 1000000009
const double eps = 1e-8;
const double PI = acos(-1.0);

//斐波那契数列求第N项
struct Mat
{
    LL data[2][2];
    Mat(LL d1, LL d2, LL d3, LL d4)
    {
        data[0][0] = d1, data[0][1] = d2, data[1][0] = d3, data[1][1] = d4;
    }
    Mat operator*(const Mat& rhs)
    {
        Mat result(0,0,0,0);
        result.data[0][0] = (data[0][0] * rhs.data[0][0] + data[0][1] * rhs.data[1][0]+ MOD )%MOD;
         result.data[0][1] = (data[0][0] * rhs.data[0][1] + data[0][1] * rhs.data[1][1]+ MOD )%MOD;
        result.data[1][0] = (data[1][0] * rhs.data[0][0] + data[1][1] * rhs.data[1][0]+ MOD )%MOD;
        result.data[1][1] = (data[1][0] * rhs.data[0][1] + data[1][1] * rhs.data[1][1]+ MOD )%MOD;
        return result;
    }
};
void Print(const Mat& tmp)
{
    cout << tmp.data[0][0] << ' ' << tmp.data[0][1] << endl;
    cout << tmp.data[1][0] << ' ' << tmp.data[1][1] << endl << endl;
}
Mat fpow(Mat a, LL b)
{
    Mat tmp = a, ret(1,0,0,1);
    while (b != 0)
    {
        //Print(ret);
        if (b & 1)
            ret = tmp*ret;
        tmp = tmp*tmp;
        b /= 2;
    }
    //Print(ret);
    return ret;
}
int main()
{
    LL x, y, n;
    while (cin >> x >> y >> n)
    {
        if (n == 1)
            cout << (x + MOD) % MOD << endl;
        else if (n == 2)
            cout << (y + MOD) % MOD << endl;
        else
        {
            Mat m = fpow(Mat(1, -1, 1, 0), n - 2);
            cout << (m.data[0][0] * y + m.data[0][1] * x + MOD) % MOD << endl;
        }
    }
}

 

其实一个滚动数组即可解决

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 50000
#define N 21
#define MOD 1000000007
#define INF 1000000009
const double eps = 1e-8;
const double PI = acos(-1.0);

LL a[N];
int main()
{
    LL x, y, n;
    while (cin >> x >> y >> n)
    {
        a[0] = (x + MOD) % MOD;
        a[1] = (y + MOD) % MOD;
        for (int i = 2; i < 6; i++)
            a[i] = (a[i - 1] - a[i - 2] + MOD) % MOD;
        cout << (a[(n - 1) % 6] + MOD) % MOD << endl;
    }
}

 

posted @ 2017-07-25 19:29  joeylee97  阅读(574)  评论(0编辑  收藏  举报