hdu 6185 Covering 矩阵快速幂

题意:

用1*2和2*1的两种地毯铺地 问有多少种情况

 

思路:

直接推转移方程

从An-1的地方只有1种转移方法

从An-2的地方有5种转移方法

n-3转移不到n

但是n-4可以 也是最复杂的

从An-4的地方有种(An-3 - An-4)转移方法

因为n-4是从红线的地方转移过来的

所以我们最后的转移方程就是

 

An = An-1 + 5*An-2 + An-3 - An-4

 

手推一下前4项 1 5 11 36

然后直接推矩阵写快速幂就行了

 

1 5 1 -1

1 0 0 0

0 1 0 0

0 0 1 0

 

坑点是因为有负数次幂 所以最后要+mod再%mod

 

最后附上快速幂模板

 

 1 #include<bits/stdc++.h>
 2 #define cl(a,b) memset(a,b,sizeof(a))
 3 #define debug(a) cerr<<#a<<"=="<<a<<endl
 4 using namespace std;
 5 typedef long long ll;
 6 typedef pair<int,int> pii;
 7 
 8 const int maxn=4;
 9 const int mod=1e9+7;
10 
11 struct matrix
12 {
13     ll a[maxn][maxn];
14     int row,col;
15     matrix():row(maxn),col(maxn){cl(a,0);}
16     matrix(int x,int y):row(x),col(y){cl(a,0);}
17     void show()
18     {
19         for(int i=0; i<row; i++)
20         {
21             for(int j=0; j<col; j++)
22             {
23                 printf("%d%c",a[i][j],j==col-1?'\n':' ');
24             }
25         }
26     }
27     inline ll* operator [] (int x)
28     {
29         return a[x];
30     }
31     inline matrix operator * (matrix x)
32     {
33         matrix tmp(row,col);
34         for (int i=0; i<row; i++)
35             for (int j=0; j<col; j++)
36                 for (int k=0; k<row; k++)
37                     tmp[i][j]=(tmp[i][j]+a[i][k]*x[k][j])%mod;
38         return tmp;
39     }
40     inline void operator *= (matrix x)
41     {
42         *this = *this * x;
43     }
44     matrix operator ^ (ll x)
45     {
46         matrix result(row,col),now=*this;
47         for(int i=0; i<row; i++)
48         {
49             result[i][i]=1;
50         }
51         while(x)
52         {
53             if(x%2) result*=now;
54             now*=now;
55             x/=2;
56         }
57         return result;
58     }
59 };
60 
61 int main()
62 {
63     ll n,a[4]= {1,5,11,36};
64     while(~scanf("%lld",&n))
65     {
66         if(n<=4)
67         {
68             printf("%lld\n",a[n-1]);
69         }
70         else
71         {
72             matrix mt(4,4);
73             mt[0][0]=1,mt[0][1]=5,mt[0][2]=1,mt[0][3]=-1;
74             mt[1][0]=1,mt[2][1]=1,mt[3][2]=1;
75             mt=mt^(n-4);
76             ll ans=0;
77             ans+=((36*mt[0][0]+11*mt[0][1]+5*mt[0][2]+1*mt[0][3])%mod+mod)%mod;
78             printf("%lld\n",ans);
79         }
80     }
81     return 0;
82 }/*
83 
84 1
85 2
86 
87 */

 

转载于:https://www.cnblogs.com/general10/p/7460776.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值