hdu5015233 Matrix 矩阵快速幂

//对于一个n*(m+1)的矩阵n<=10 ,m<=1e9 
//a[0][0] = 0 , a[0][1] = 233 , a[0][2] = 2333 , a[0][3] = 23333...
//给出a[1][0] ... a[n][0]
//其他的a[i][j] = a[i-1][j] + a[i][j-1]
//可以推到a[n][m] = a[n][m-1] + a[n-1][m-1] + a[n-2][m-1] + ... + a[1][m-1] + a[0][m]
//a[0][m] = a[0][m-1]*10 + 3
//可以通过这个递推式构造矩阵
//  a[n][m]    1 1 1 ... 1  0    a[n][m-1]
// a[n-1][m]   0 1 1 ... 1  0    a[n-1][m-1]
// a[n-2][m]   0 0 1 ... 1  0    a[n-2][m-1]
//  ...            ...          ...
// a[0][m+1]   0 0 0 ... 10 3    a[0][m-1]
//    1        0 0 0 ... 0  1       1
#include
#include
#include
using namespace std ;
const int maxn = 15 ;
typedef long long ll ;
const ll mod = 10000007 ;
int n , m ;
ll a[maxn] ;
struct node
{
    ll p[maxn][maxn] ;
};
node mul(node a , node b)
{
    node c ;
    for(int i = 1;i <= n;i++)
      for(int j = 1;j <= n;j++)
      {
          c.p[i][j] = 0 ;
          for(int k = 1;k <= n;k++)
          c.p[i][j] = (c.p[i][j] + a.p[i][k]*b.p[k][j])%mod ;
      }
    return c ;
}
node pow(node a , int k)
{
    node c ;
    memset(c.p , 0 , sizeof(c.p)) ;
    for(int i = 1;i <= n;i++)
    c.p[i][i] = 1 ;
    while(k)
    {
        if(k&1)c = mul(c , a) ;
        a = mul(a , a) ;
        k >>= 1 ;
    }
    return c ;
}
int main()
{
    //freopen("in.txt" , "r" , stdin) ;
    while(~scanf("%d%d" , &n , &m))
    {
        node b ;
        memset(b.p ,  0 , sizeof(b)) ;
        for(int i = 1;i <= n;i++)
        scanf("%lld" , &b.p[n - i + 1][1]) ;
        b.p[n+1][1] = 233 ;
        b.p[n+2][1] = 1 ;
        node a ;
        memset(a.p , 0 , sizeof(a.p)) ;
        for(int i = 1;i <= n;i++)
           for(int j = i;j <= n + 1;j++)
           a.p[i][j] = 1 ;
        a.p[n+1][n+1] = 10 ;
        a.p[n+1][n+2] = 3 ;
        a.p[n+2][n+2] = 1 ;
        n += 2;
        a = pow(a , m) ;
        node c = mul(a , b) ;
        cout<

你可能感兴趣的:(矩阵快速幂)