您的位置:首页 > 其它

Hdu 5015 233 Matrix (矩阵乘法)

2014-09-16 10:23 351 查看
题目链接

233 Matrix

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 503 Accepted Submission(s): 316



[align=left]Problem Description[/align]
In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 23333, or 233333 ... in the same meaning. And here is the question: Suppose we have a matrix called 233 matrix. In the first line, it would be
233, 2333, 23333... (it means a0,1 = 233,a0,2 = 2333,a0,3 = 23333...) Besides, in 233 matrix, we got ai,j = ai-1,j +ai,j-1( i,j ≠ 0). Now you have known a1,0,a2,0,...,an,0,
could you tell me an,m in the 233 matrix?

[align=left]Input[/align]
There are multiple test cases. Please process till EOF.

For each case, the first line contains two postive integers n,m(n ≤ 10,m ≤ 109). The second line contains n integers, a1,0,a2,0,...,an,0(0 ≤ ai,0 < 231).

[align=left]Output[/align]
For each case, output an,m mod 10000007.

[align=left]Sample Input[/align]

1 1
1
2 2
0 0
3 7
23 47 16


[align=left]Sample Output[/align]

234
2799
72937


题意:一个矩阵,a(0,1)=233,a(0,2)=2333,a(0,3)=23333,a(0,4)=233333.......,告诉你n,m,并且给你a(1,0),a(2,0)......a(n,0)。

a(i,j)=a(i-1,j)+a(i,j-1),1<=i,j。求a(n,m)。n<=10,m<=1000000000。

题解:由于n很小,m很大,所以容易想到构造矩阵,并用矩阵二分幂来解。我们用l1,l2....ln,表示当前列的值,初始值为a(1,0),....a(n,0)。设当前列的下一列为b1,b2,....bn。那么容易得出b1=l1+2333..,b2=l1+l2+2333..,b3=l1+l2+2333...,bn=l1+l2+..ln+2333..。而下一列的23333=当前列2333*10+3。那么我们可以这样构造矩阵,假设n==4。

l1 1 0 0 0 1 0 b1

l2 1 1 0 0 1 0 b2

l3 * 1 1 1 0 1 0 = b3

l4 1 1 1 1 1 0 b4

233.. 0 0 0 0 10 3 233..*10+3

1 0 0 0 0 0 1 1

这样我们就可以用当前列推出下一列,我们就可以用矩阵二分幂求解了。

#include<stdio.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#define inff 0x3fffffff
#define eps 1e-8
#define nn 210000
#define mod 10000007
typedef __int64 LL;
using namespace std;
int N,M;
LL aa[20];
const int MAXN=20;
const int MAXM=20;
struct Matrix
{
int n,m;
LL a[MAXN][MAXM];
void clear()
{
n=m=0;
memset(a,0,sizeof a);
}
Matrix operator *(const Matrix &b) const
{
Matrix tmp;
tmp.clear();
tmp.n=n; tmp.m=b.m;
for(int k=0; k<m; k++)
for(int i=0; i<n; i++)
for(int j=0; j<b.m; j++)
{
tmp.a[i][j]+=(a[i][k]*b.a[k][j])%mod;
tmp.a[i][j]%=mod;
}
return tmp;
}

}ma,ans;
Matrix operator ^(Matrix x,int p)
{
Matrix ret;
ret.clear();
ret.n=x.n; ret.m=x.m;
for(int i=0; i<x.n; i++)
for(int j=0; j<x.m; j++)
ret.a[i][j] = (i == j ? 1 : 0);
while(p)
{
if(p%2) ret = ret * x;
x = x * x;
p /= 2;
}
return ret;
}
int main()
{
int i,j;
while(scanf("%d%d",&N,&M)!=EOF)
{
for(i=0;i<N;i++)
{
scanf("%I64d",&aa[i]);
aa[i]%=mod;
}
ma.clear();
ma.n=ma.m=N+2;
for(i=0;i<N;i++)
{
for(j=0;j<=i;j++)
ma.a[i][j]=1;
ma.a[i]
=1;
}
ma.a

=10;
ma.a
[N+1]=3;
ma.a[N+1][N+1]=1;
ans.clear();
ans.n=N+2,ans.m=1;
for(i=0;i<N;i++)
ans.a[i][0]=aa[i];
ans.a
[0]=233;
ans.a[N+1][0]=1;
ans=(ma^M)*ans;
printf("%I64d\n",ans.a[N-1][0]);
}
return 0;
}


看了大神的代码,只跑了31ms,好像直接推出了公式,orz。。。。先贴在这里,有空再学学。

#include<stdio.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<iostream>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#define inff 0x3fffffff
#define eps 1e-8
#define nn 210000
#define mod 10000007
typedef __int64 LL;
using namespace std;
int N,M;
LL aa[20];
const int MAXN=20;
const int MAXM=20;
struct Matrix
{
int n,m;
LL a[MAXN][MAXM];
void clear()
{
n=m=0;
memset(a,0,sizeof a);
}
Matrix operator *(const Matrix &b) const
{
Matrix tmp;
tmp.clear();
tmp.n=n; tmp.m=b.m;
for(int k=0; k<m; k++)
for(int i=0; i<n; i++)
for(int j=0; j<b.m; j++)
{
tmp.a[i][j]+=(a[i][k]*b.a[k][j])%mod;
tmp.a[i][j]%=mod;
}
return tmp;
}

}ma,ans;
Matrix operator ^(Matrix x,int p)
{
Matrix ret;
ret.clear();
ret.n=x.n; ret.m=x.m;
for(int i=0; i<x.n; i++)
for(int j=0; j<x.m; j++)
ret.a[i][j] = (i == j ? 1 : 0);
while(p)
{
if(p%2) ret = ret * x;
x = x * x;
p /= 2;
}
return ret;
}
int main()
{
int i,j;
while(scanf("%d%d",&N,&M)!=EOF)
{
for(i=0;i<N;i++)
{
scanf("%I64d",&aa[i]);
aa[i]%=mod;
}
ma.clear();
ma.n=ma.m=N+2;
for(i=0;i<N;i++)
{
for(j=0;j<=i;j++)
ma.a[i][j]=1;
ma.a[i]
=1;
}
ma.a

=10;
ma.a
[N+1]=3;
ma.a[N+1][N+1]=1;
ans.clear();
ans.n=N+2,ans.m=1;
for(i=0;i<N;i++)
ans.a[i][0]=aa[i];
ans.a
[0]=233;
ans.a[N+1][0]=1;
ans=(ma^M)*ans;
printf("%I64d\n",ans.a[N-1][0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: