CodeForces 450B Jzzhu and Sequences

题目链接:http://codeforces.com/problemset/problem/450/B

将题目给出的递推公式稍作变换,

fn = fn-1 - fn-2

化为矩阵形式,用矩阵快速幂运算进行求解。

注意题目直接使用%运算符可能得到负数的结果,对与负数x,x%modnum后,还要将结果加上modnum,这样就能保证结果在0 ~ modnum-1的范围内。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <map>
 4 #include <vector>
 5 #include <functional>
 6 #include <string>
 7 #include <cstring>
 8 #include <queue>
 9 #include <set>
10 #include <cmath>
11 #include <cstdio>
12 using namespace std;
13 #define IOS ios_base::sync_with_stdio(false)]
14 typedef long long LL;
15 const int INF=0x3f3f3f3f;
16 
17 const int modnum=1000000007;
18 const int maxn=3;
19 typedef struct matrix{
20     int v[maxn][maxn];
21     void init(){memset(v,0,sizeof(v));}
22 }M;
23 inline int mod(LL x){if(x<0) return int(x%modnum+modnum); return int(x%modnum);}
24 M mul_mod(const M &a,const M &b,int L,int m,int n)
25 {
26     M c; c.init();
27     for(int i=0;i<L;i++){
28         for(int j=0;j<n;j++){
29             for(int k=0;k<m;k++)//注意j,k范围
30                 c.v[i][j]=mod(c.v[i][j]+mod((LL)a.v[i][k]*b.v[k][j]));
31         }
32     }
33     return c;
34 }
35 M power(M x,int L,int p)
36 {
37     M tmp; tmp.init();
38     for(int i=0;i<L;i++)
39         tmp.v[i][i]=1;
40     while(p){
41         if(p&1) tmp=mul_mod(x,tmp,L,L,L);
42         x=mul_mod(x,x,L,L,L);
43         p>>=1;
44     }
45     return tmp;
46 }
47 
48 int main()
49 {
50     int x,y,n;
51     M a,b;
52     while(scanf("%d%d%d",&x,&y,&n)==3){
53         x=mod(x); y=mod(y);
54         if(n==1){printf("%d
",x); continue;}
55         if(n==2){printf("%d
",y); continue;}
56         a.init();
57         a.v[0][0]=a.v[1][0]=1;
58         a.v[0][1]=-1;
59         b.init();
60         b.v[0][0]=y;
61         b.v[1][0]=x;
62         a=power(a,2,n-2);
63         a=mul_mod(a,b,2,2,1);
64         printf("%d
",a.v[0][0]);
65     }
66 }
View Code
原文地址:https://www.cnblogs.com/cumulonimbus/p/5695493.html