标签:
题意:给出矩阵的第0行(233,2333,23333,...)和第0列a1,a2,...an(n<=10,m<=10^9),给出递推式: A[i][j] = A[i-1][j] + A[i][j-1],要求A[n][m]。
数据范围:n,m(n ≤ 10,m ≤ 109).
思路:因为m ≤ 109 显然是要找到列与列的递推关系,用logn幂加速。
从递推式可以得知:a[i][j]可以由a[1...i][j-1] 递推得到,所以构造递推矩阵实现a[1...1][j-1]向a[1...1][j]的转移‘即可
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod = 10000007;
struct mat
{
ll a[15][15];
mat()
{
memset(a,0,sizeof(a));
}
};
ll I[15];
mat S;
int n,m;
void print(mat m)
{
for(int i=1;i<=n;i++,puts(""))
for(int j=1;j<=n;j++)
printf("%d ",m.a[i][j]);
}
mat mul(mat m1,mat m2)
{
mat ans;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(m1.a[i][j])
for(int k=1;k<=n;k++)
ans.a[i][k]=( ans.a[i][k]+m1.a[i][j]*m2.a[j][k] )%mod;
return ans;
}
mat quickmul(mat m,int k)
{
mat ans;
for(int i=1;i<=n;i++) ans.a[i][i]=1;
while(k)
{
if(k&1) ans=mul(ans,m);
m=mul(m,m);
k>>=1;
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
n+=2;
I[1]=23,I[n]=1;
for(int i=2;i<n;i++) scanf("%I64d",&I[i]);
for(int i=1;i<n;i++)//构造矩阵
{
S.a[i][1]=10;
for(int j=2;j<=i;j++) S.a[i][j]=1;
for(int j=i+1;j<n;j++) S.a[i][j]=0;
S.a[i][n]=3;
}
for(int i=1;i<=n;i++) S.a[n][i]=(i==n);
mat t=quickmul(S,m);
ll ans=0;
for(int i=1;i<=n;i++)
ans+=I[i]*t.a[n-1][i];
printf("%I64d\n",ans%mod);
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/kalilili/article/details/44975473