CodeForces 450B 矩阵
A - Jzzhu and Sequences
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Appoint description:
Description
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 Input
Input
2 3
3
Output
1
Input
0 -1
2
Output
1000000006
Hint
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).
观察他的公式f[1] = x,f[2] = y,f[i] = f[i] - f[i-1];
可以得到 | -1 1 | ^((n%2 ? n:(--n))/2) × | f[1] | = | f[n] |
| -1 0 | | f[2] | | f[n+1] |
这样只要处理矩阵的次方后就能得出答案。
#include<map> #include<set> #include<string> #include<queue> #include<stack> #include<cmath> #include<vector> #include<cstdio> #include<time.h> #include<cstring> #include<iostream> #include<algorithm> #define INF 1000000001 #define ll long long #define MOD 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int MAXN = 100010; int x,y; ll n; struct Mat { ll a[4][4]; }; Mat operator *(Mat a,Mat b) { Mat c; memset(c.a,0,sizeof(c.a)); for(int i = 0; i < 2; i++){ for(int j = 0; j < 2; j++){ for(int k = 0; k < 2;k++){ c.a[i][j] += ((a.a[i][k] * b.a[k][j]) % MOD + MOD) % MOD; c.a[i][j] = ((c.a[i][j])% MOD + MOD) % MOD; } } } return c; } Mat mod_pow(Mat b,int n) { Mat c; c.a[0][0] = c.a[1][1] = 1; c.a[0][1] = c.a[1][0] = 0; while(n){ if(n & 1){ c = c * b; } b = b * b; n >>= 1; } return c; } int main() { while(~scanf("%d%d%lld",&x,&y,&n)){ if(n == 1){ x = (x%MOD + MOD)%MOD; cout<<x<<endl; continue; } else if(n == 2){ y = (y%MOD + MOD)%MOD; cout<<y<<endl; continue; } else { Mat b; b.a[0][0] = -1; b.a[0][1] = 1; b.a[1][0] = -1; b.a[1][1] = 0; int t = n; if(t % 2 == 0)t --; b = mod_pow(b,t/2); ll ans; if(n % 2){ ans = ((b.a[0][0] * x)%MOD + (b.a[0][1] * y)%MOD + MOD)%MOD; } else { ans = ((b.a[1][0] * x)%MOD + (b.a[1][1] * y)%MOD + MOD)%MOD; } cout<<(ans + MOD) % MOD<<endl; } } return 0; }