cf 450b 矩阵快速幂(数论取模 一大坑点啊)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cf 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).
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 a single integer representing fn modulo 1000000007 (109?+?7).
2 3
3
1
0 -1
2
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).
题意 : 显然是矩阵快速幂么
坑点 : 就是数论取模这一块 , 稍不注意就错了
const ll mod = 1e9+7; const double pi = acos(-1.0); const int inf = 0x3f3f3f3f; #define Max(a,b) a>b?a:b #define Min(a,b) a>b?b:a struct mat { ll a[2][2]; }; mat mul(mat a, mat b){ mat r; memset(r.a, 0, sizeof(r.a)); for(int i = 0; i < 2; i++){ for(int k = 0; k < 2; k++){ if (a.a[i][k]){ for(int j = 0; j < 2; j++){ if (b.a[k][j]){ r.a[i][j] += (a.a[i][k] * b.a[k][j] + mod)%mod; r.a[i][j] = (r.a[i][j] + mod)%mod; } } } } } return r; } mat pow(mat a, int n){ mat b; for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) if (i == j) b.a[i][i] = 1; else b.a[i][j] = 0; while(n){ if (n & 1) b = mul(a, b); a = mul(a, a); n >>= 1; } return b; } int main() { ll x, y, n; scanf("%lld%lld%lld", &x, &y, &n); mat a; a.a[0][0] = a.a[1][0] = 1; a.a[0][1] = -1; a.a[1][1] = 0; if (n == 1){ printf("%lld\n", (x+mod)%mod); } else if (n == 2){ printf("%lld\n", (y+mod)%mod); } else { a = pow(a, n-2); ll ans = ((a.a[0][0]*y+mod)%mod + (a.a[0][1]*x+mod)%mod + mod)%mod; // 重点就是这里 //ll ans = (a.a[0][0]*y+a.a[0][1]*x+mod)%mod; //ans = (ans + mod)%mod; printf("%lld\n", ans ); } return 0; } /* -9 -11 12345 */
以上是关于cf 450b 矩阵快速幂(数论取模 一大坑点啊)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 450B div.2 Jzzhu and Sequences 矩阵快速幂or规律
HDU 5895 Mathematician QSC(矩阵乘法+循环节降幂+除法取模小技巧+快速幂)