矩阵快速幂

  1 /*
  2   题意:求a(n)=a(n-1)+a(n-2)+a(n-3)+......a(n-k)+...     k<20      n<10^18
  3   题解:矩阵快速幂,把递推公式写成矩阵的形式,就可以利用快速幂计算
  4   时间:2018.07.31
  5 */
  6 
  7 #include <bits/stdc++.h>
  8 using namespace std;
  9 
 10 typedef long long LL;
 11 const int MAXN = 100005;
 12 const LL MOD7 = 1e9+7;
 13 const LL MOD9 = 1e9+9;
 14 
 15 
 16 int n,K;
 17 LL m;
 18 
 19 struct Matrix
 20 {
 21     LL a[25][25];
 22     int n;
 23     Matrix()
 24     {
 25         memset(a,0LL,sizeof(a));
 26         n= 20;
 27     }
 28     Matrix(int n):n(n)
 29     {
 30         memset(a,0LL,sizeof(a));
 31     }
 32     Matrix(const Matrix& T)
 33     {
 34         this->n = T.n;
 35         for (int i=0;i<n;++i)
 36         {
 37             for (int j=0;j<n;++j)
 38             {
 39                 a[i][j]=T.a[i][j];
 40             }
 41         }
 42     }
 43 
 44     Matrix operator*(const Matrix& T)
 45     {
 46         Matrix c(n);
 47         for (int i=0;i<n;++i)
 48         {
 49             for (int j=0;j<n;++j)
 50             {
 51                 for (int k=0;k<n;++k)
 52                 {
 53                     c.a[i][j]=(c.a[i][j] + a[i][k]*T.a[k][j] % MOD9) % MOD9;
 54                 }
 55             }
 56         }
 57         return c;
 58     }
 59 
 60     Matrix operator+(const Matrix &T)
 61     {
 62         Matrix c(n);
 63         for (int i=0;i<n;++i)
 64         {
 65             for (int j=0;j<n;++j)
 66             {
 67                 c.a[i][j] = (c.a[i][j]+a[i][j]+T.a[i][j])%MOD9;
 68             }
 69         }
 70         return c;
 71     }
 72 
 73     Matrix operator=(const Matrix &T)
 74     {
 75         this->n=T.n;
 76         for (int i=0;i<n;++i)
 77         {
 78             for (int j=0;j<n;++j)
 79             {
 80                 a[i][j]=T.a[i][j];
 81             }
 82         }
 83     }
 84 
 85     void ones()
 86     {
 87         for (int i=0;i<n;++i) a[i][i]=1;
 88     }
 89 
 90     void Print()
 91     {
 92         for (int i=0;i<n;++i)
 93         {
 94             for (int j=0;j<n;++j)
 95             {
 96                 printf("%lld ",a[i][j]);
 97             }
 98             printf("\n");
 99         }
100     }
101 };
102 
103 Matrix Pow(Matrix a, LL b)
104 {
105     Matrix res(a.n);
106     res.ones();
107     Matrix ans(a);
108     while (b)
109     {
110         if (b&1) res=res*ans;
111         ans=ans*ans;
112         b>>=1;
113     }
114     return res;
115 }
116 
117 int b[25];
118 
119 int main()
120 {
121 #ifndef ONLINE_JUDGE
122     freopen("test.txt","r",stdin);
123 #endif // ONLINE_JUDGE
124     while (scanf("%d%lld%d",&n,&m,&K)!=-1)
125     {
126         for (int i=1;i<=n;++i) scanf("%d",&b[n-i+1]);
127         Matrix a(n);
128         for (int i=0;i<n-1;++i) a.a[i][i+1]=1;
129         int ck;
130         for (int i=1;i<=K;++i)
131         {
132             scanf("%d",&ck);
133             a.a[ck-1][0]+=1;
134         }
135         // a.Print();
136         if (m<=n) {
137             printf("%d\n",b[n-m+1]);
138             continue;
139         }
140         a=Pow(a,m-n);
141         // a.Print();
142         LL ans=0;
143         for (int i=0;i<n;++i)
144             ans = (ans + b[i+1]*a.a[i][0]) % MOD9;
145         printf("%lld\n",ans);
146     }
147     return 0;
148 }

 

posted @ 2018-07-31 21:24  LeeSongt  阅读(184)  评论(0编辑  收藏  举报