HDU --- 5015 233 Matrix 【思维 + 矩阵快速幂】

传送门

思路 :
第一列元素为:
0
a1
a2
a3
a4

转化为:
23
a1
a2
a3
a4
3
则第二列为:
23*10+3
23*10+3+a1
23*10+3+a1+a2
23*10+3+a1+a2+a3
2*10+3+a1+a2+a3+a4
3
所以就可以建立矩阵, 然后求相应的列数就可以啦!

AC Code

#include
#define CLR(x) memset(x,0,sizeof(x))
#define ll long long int
#define PI acos(-1.0)
#define db double
#define mod 10000007
using namespace std;
const int maxn=1e5+5;
int r,c;
struct Ma{
    ll a[15][15];
    void cc(){
        CLR(a);
    }
    Ma operator * (const Ma &b) const {
        Ma tmp;
        tmp.cc();
        for(int i=0;i<=r+1;i++){
            for(int j=0;j<=r+1;j++){
                for(int k=0;k<=r+1;k++){
                    tmp.a[i][j] += (a[i][k] * b.a[k][j]);
                    tmp.a[i][j] %= mod;
                }
            }
        }
        return tmp;
    }
}res,x;

void init()
{
    res.cc();
    x.cc();
    for(int i=0;i<=r+1;i++)
        res.a[i][i]=1;

    for(int i=0;i<=r;i++){
        x.a[0][i] = 10;
        x.a[r+1][i] = 1;
    }
    x.a[r+1][r+1]=1;
    for(int i=1;i<=r;i++){   //必须根据具体行数来建造矩阵. 不能建一个确定大小的矩阵, 会影响其他列的情况.
        for(int j=i;j<=r;j++){
            x.a[i][j] = 1;
        }
    }
}

void qpow(int t)
{
    while(t){
        if(t&1) res = res * x;
        x = x*x;
        t >>= 1;
    }
}

int main()
{
    while(scanf("%d%d",&r,&c)!=EOF){
        int b[15];
        CLR(b);
        b[0]=23;
        for(int i=1;i<=r;i++)
            scanf("%d",&b[i]);
        b[r+1]=3;
        init();
        qpow(c);
        ll ans = 0;
        for(int i=0;i<=r+1;i++){
            ans += res.a[i][r] * b[i];
            ans %= mod;
        }
        printf("%lld\n",ans);
    }
}

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