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).
InputThe first line contains two integers x and y (|x|, |y| ≤ 109). The second line contains a single integer n (1 ≤ n ≤ 2·109).
Output a single integer representing fn modulo 1000000007 (109 + 7).
Input
2 3
3
Output
1
Input
0 -1
2
Output
1000000006
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).
第一次用矩阵快速幂 做不出来 可能是因为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; } }