hdu 5015

思路:

第一列元素为:

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

23*10+3+a1+a2+a3+a4

3

根据前后两列的递推关系,有等式可得矩阵A的元素为:

嗯,然后跑矩阵快速幂就好了,这里的递推公式是一列一列的来,这个得理清楚。

ac代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#define mt(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
const ll mod=10000007;
struct Martix
{
    ll mp[20][20];
    ll r,c;
};
Martix mul(Martix a,Martix b)
{
    ll r=a.r;
    ll c=b.c;
    Martix temp;
    temp.r=r;
    temp.c=c;
    for(int i=0;i<r;i++)
    {
        for(int j=0;j<c;j++)
        {
            temp.mp[i][j]=0;
            for(int k=0;k<r;k++)
            {
                temp.mp[i][j]=(a.mp[i][k]*b.mp[k][j]%mod+temp.mp[i][j])%mod;
            }
        }
    }
    return temp;
}
ll temp[20];
ll n,m;
int pow(Martix a,int k)
{
    Martix ans; // 
    ans.r=n+2;
    ans.c=1;
    memset(ans.mp,0,sizeof(ans.mp));
    ans.mp[0][0]=23;
    for(int i=1;i<=n;i++) ans.mp[i][0]=temp[i];
    ans.mp[n+1][0]=3;
  //  for(int i=0;i<n+2;i++) cout<<ans.mp[i][0]<<' ';
   // cout<<endl;
    while(k)
    {
        if(k&1) ans=mul(a,ans);
        k/=2;
        a=mul(a,a);
    }
  // for(int i=0;i<n+2;i++) cout<<ans.mp[i][0]<<' ';
   // cout<<endl;
    return ans.mp[n][0]%mod;
}
int main()
{

    while(~scanf("%lld %lld",&n,&m))
    {
        Martix a;// 系数矩阵
        memset(temp,0,sizeof(temp));
        for(int i=1;i<=n;i++) scanf("%lld",&temp[i]);
        if(n==0)
        {
            cout<<temp[m]%mod<<endl;
            continue;
        }
        a.r=n+2;
        a.c=n+2;
        memset(a.mp,0,sizeof(a.mp));
        a.mp[0][0]=10;
        a.mp[0][n+1]=1;
        for(int i=1;i<=n;i++)
        {
            a.mp[i][0]=10;
            a.mp[i][n+1]=1;
            for(int j=1;j<=i;j++) a.mp[i][j]=1;
        }
        a.mp[n+1][n+1]=1;
        ll key=pow(a,m);
        cout<<key<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/z1141000271/p/7530573.html