HDU 5015 233 Matrix 矩陣快速冪
阿新 • • 發佈:2018-12-13
題意就是
現在有一個矩陣a,矩陣的第一行和第一列(出了a[0][0]) 給你, 讓你求a[n][m]
第一行是 a[0][1] = 233 , a[0][2] = 2333 , a[0][i] = a[0][i-1] * 10 + 3
a[i][j] = a[i-1][j] + a[i][j-1]
看題目:應該是矩陣快速冪了
舉個例子:
輸入:
3 1
23 47 16
我們手推一下a[3][1]
那a[1][2] = 2333 + 23 + 233
所以我們初始矩陣是一個 (1)列(n +2)行的矩陣
當n是3的時候 初始矩陣為
然後用來快速冪的矩陣為
n為3的時候 m=1的時候
然後就是愉快的擼程式碼了
// // HDU5015 - 233Matrix.cpp // 數論 // // Created by Terry on 2018/10/1. // Copyright © 2018年 Terry. All rights reserved. // #include <stdio.h> typedef long long LL; long long read(){ long long x = 0, f = 1; char ch=getchar(); while(ch < '0' || ch > '9'){if(ch=='-') f = -1; ch = getchar();} while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();} return x * f; } const int maxn = 12; const long long mod = 10000007; struct Matrix{ long long m[maxn][maxn]; }unit; long long int N, M; Matrix operator * (Matrix a, Matrix b){ Matrix ret; LL x; long long int n = N + 2; // [0 - N+1][0 - N+1] for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ x = 0; for(int k = 0; k < n; ++k){ x += ((LL)a.m[i][k] * b.m[k][j]) % mod; } ret.m[i][j] = (x) % mod; } } return ret; } void init_unit(){ // 單位矩陣 for(int i = 0; i < maxn; ++i){ unit.m[i][i] = 1; } } Matrix pow_mat(Matrix a, LL n){ Matrix ans = unit; while (n) { if(n & 1){ ans = ans * a; } a = a * a; n >>= 1; } return ans; } int main(){ init_unit(); while (scanf("%lld%lld", &N, &M) != EOF) { Matrix ans, a; ans.m[0][0] = 23; for(int i = 1; i <= N; ++i){ ans.m[0][i] = read(); } ans.m[0][N + 1] = 3; // 構造快速冪用的矩陣 long long int x = N + 1; for(int i = 0; i <= x; i++){ for(int j = 0; j <= x; j++){ a.m[i][j] = 0; } } for(int i = 0; i < x; i++){ a.m[0][i] = 10; a.m[x][i] = 1; } a.m[x][x] = 1; for(int i = 1; i < x; i++){ for(int j = 1; j <= i; j++){ //printf("%d %d\n", j, i); a.m[j][i] = 1; } } // 求a[n][m] a = pow_mat(a, M); ans = ans * a; printf("%lld\n", ans.m[0][N] % mod); } return 0; }