【HDU5015】233 Matrix
題意
給出矩陣的第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]。
分析
推單位矩陣,先開始沒想出來,於是看了題解,但是沒有看懂,只有又自己推,然後發現就推出來了誒
不要把菜當做不思考的藉口
第0列是告訴了的,忽略,從第1列開始看,第一列是
233
a1
a2
a3
a4
...
an
觀察到第二列是2333,會出現一個3,於是我們乾脆在每一列後面補一個3方便遞推
於是第一列和第二列分別是
233 2333
a1
a2 2333+a1+a2
a3
a4 2333+a1+a2+a3+a4
... ...
an 2333+a1+a2+...+an-1+an
3 3
想從第一列得到第二列,那需要乘什麼呢?肯定是個n+2行n+2列的矩陣
直接推發現2333=233*10+3
於是第一行10 0 0 ...0 0 1
2333+a1=233*10+3+a1
於是第二行 10 1 0 ... 0 0 1
類推可得到單位矩陣
10 0 0 ...0 0 1
10 1 0 ...0 0 1
10 1 1 ...0 0 1
10 1 1 ...1 0 1
10 1 1 ...1 1 1
0 0 0 ... 0 0 1
將這個矩陣求m-1次方再與原來的第一列相乘,就可求出A[n][m],第1列用第0列推出
或者是直接用第0列,求m次方
程式碼
#include<bits/stdc++.h> using namespace std; #define N 15 #define ll long long #define mod 10000007 ll n,m,f; ll one[N]; struct email { ll x[N][N]; }a,ans; inline void init() { one[0]=23;one[n+1]=3; for(ll i=1;i<=n;i++)scanf("%lld",&one[i]); memset(a.x,0,sizeof(a.x)); for(ll i=0;i<=n;i++)a.x[i][0]=10,a.x[i][n+1]=1; a.x[n+1][n+1]=1; for(ll i=1;i<=n;i++) for(ll j=1;j<=i;j++) a.x[i][j]=1; } inline email mul(email a,email b) { email c; memset(c.x,0,sizeof(c.x)); for(ll i=0;i<=n+1;i++) for(ll j=0;j<=n+1;j++) for(ll k=0;k<=n+1;k++) c.x[i][j]+=a.x[i][k]*b.x[k][j],c.x[i][j]%=mod; return c; } inline email ksm(email a,ll m) { if(m==1)return a; email b=ksm(a,m/2); b=mul(b,b); if(m&1)b=mul(b,a); return b; } int main() { while(scanf("%lld%lld",&n,&m)==2) { init(); ans=ksm(a,m);f=0; for(ll i=0;i<=n+1;i++) f+=ans.x[n][i]*one[i],f%=mod; printf("%lld\n",f); } return 0; }