1. 程式人生 > 實用技巧 >Codeforces 450B 矩陣快速冪

Codeforces 450B 矩陣快速冪

xg

題意

  f1為x,f2為y,fi=fi-1 + fi+1,求fn為多少(n=2e9)

思路

  這題不用矩陣快速冪也可。

  換算式子為fi = fi-1 - fi-2。

  則易看出令f1 = {x,y},矩陣A為{{0,-1},{1,1}};

  答案即為f1 * An-1,因為存在負數,負數取模為(a%mod+mod)%mod

#include <iostream>
#include <cstdio>
#include<string>
#include<cstring>
using namespace std;
typedef long
long ll; const int maxn = 2e5+10; const int mod = 1e9+7; int n; void mul(ll f[2] ,ll a[2][2]) { ll c[2]; memset(c,0,sizeof(c)); for(int j = 0;j < 2; ++j) for(int k = 0;k < 2 ;++k) c[j] = ((c[j] + ((f[k] * a[k][j])%mod+mod)%mod) % mod+mod)%mod; memcpy(f,c,sizeof
(c)); } void mulself(ll a[2][2]) { ll c[2][2]; memset(c,0,sizeof(c)); for(int i = 0;i < 2;++i) for(int j = 0;j < 2; ++j) for(int k = 0;k < 2 ;++k) c[i][j] = ((c[i][j] + ((a[i][k] * a[k][j])%mod+mod)%mod) % mod+mod)%mod; memcpy(a,c,sizeof(c)); }
int main() { //freopen("input.txt", "r", stdin); int x,y,n; scanf("%d%d%d",&x,&y,&n); ll f[2] = {x,y}; ll a[2][2] = {{0,-1},{1,1}}; n--; for(;n;n>>=1){ //cout<<"Ssss"<<endl; if(n&1){ mul(f,a); } mulself(a); } printf("%d\n",(f[0]%mod+mod)%mod ); }