首页 > 代码库 > NOIP2016模拟 妹子(矩阵快速幂)

NOIP2016模拟 妹子(矩阵快速幂)

技术分享

技术分享

 1 #include "bits/stdc++.h"
 2 #define mem(a,b) memset(a,b,sizeof(a))
 3 using namespace std;
 4 typedef long long LL;
 5 const int MAX=105;
 6 const int MOD=1000000007;
 7 LL n,m;
 8 struct Mat{
 9     LL x,y;
10     LL mat[MAX][MAX];
11     Mat (){x=y=0,mem(mat,0);}
12     Mat operator *(const Mat &cc){
13         LL i,j,k;
14         Mat vv;
15         vv.x=x,vv.y=cc.y;
16         for (i=1;i<=vv.x;i++)
17          for (k=1;k<=cc.x;k++)
18           if (mat[i][k])
19            for (j=1;j<=vv.y;j++)
20             vv.mat[i][j]=(vv.mat[i][j]+mat[i][k]*cc.mat[k][j])%MOD;
21         return vv;
22     }
23 }a,ans;
24 Mat ksm(Mat p,int k){
25     int i,j;
26     Mat an;
27     an.x=p.x,an.y=p.y;
28     for (i=1;i<=an.x;i++)
29      an.mat[i][i]=1;
30     while (k){
31         if (k&1)
32          an=an*p;
33         p=p*p;
34         k>>=1;
35     }
36     return an;
37 }
38 int main(){
39     freopen ("harem.in","r",stdin);
40     freopen ("harem.out","w",stdout);
41     LL i,j;
42     scanf("%lld%lld\n",&n,&m);
43     char c;
44     for (i=1;i<=m;i++){
45         for (j=1;j<=m;j++){
46             c=getchar();
47             if (c==0)
48              a.mat[i][j]=1;
49         }
50         c=getchar();
51     }
52     for (i=1;i<=m+1;i++)
53      a.mat[i][m+1]=a.mat[m+1][i]=1;
54     a.x=m+1,a.y=m+1;
55     ans.x=m+1;ans.y=1;
56     for (i=1;i<=ans.x;i++)
57      ans.mat[i][1]=1;
58     ans=ksm(a,n-1)*ans;
59     LL Ans(0);
60     for (i=1;i<=m+1;i++)
61      Ans=(ans.mat[i][1]+Ans)%MOD;
62     printf("%lld",Ans);
63     return 0;
64 }

 

NOIP2016模拟 妹子(矩阵快速幂)