2015 多校联赛 ——HDU5302(矩阵快速幂)
The Goddess Of The Moon
Sample Input
2
10 50
12 1213 1212 1313231 12312413 12312 4123 1231 3 131
5 50
121 123 213 132 321
Sample Output
86814837
797922656
题意:给你n个字符串,若是一个的后缀与一个的前缀相同的大于1,则表示这两个可以连接到一起,问M个字符串相连的方案数
若a b可以合并,可以让他们相连,然后求在一个图中走m-1步的方案数,
两点之间所走的步数为m-1的不同走法有多少种——矩阵快速幂的经典问题
因为求不同方案--->去重
(在别人博客看到的,表示以前并不知道这个,既然有点像模板题,写写学习下)
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int maxn = 55; const int mod = 1e9+7; int n, m, a[maxn]; struct Mat { int s[maxn][maxn]; Mat () { memset(s, 0, sizeof(s)); } Mat operator * (const Mat& b) { Mat ret; for (int k = 0; k < n; k++) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) ret.s[i][j] = (ret.s[i][j] + 1LL * s[i][k] * b.s[k][j] % mod) % mod; } } return ret; } }; bool work(int a,int b) { char p[15], q[15]; sprintf(p, "%d", a); sprintf(q, "%d", b); int l1 = strlen(p); int l2 = strlen(q); for(int i = 0; i < l1; i++) { int k = 0; while(i + k < l1 && k < l2 && p[i+k] == q[k]) { k++; } if(i + k == l1 && k > 1) return true; } return false; } Mat solve() { Mat lp; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { if(work(a[i],a[j])) lp.s[i][j] = 1; } return lp; } Mat pow_mat(Mat x, int z) { Mat ret; for (int i = 0; i < n; i++) ret.s[i][i] = 1; while (z) { if (z&1) ret = ret * x; x = x * x; z >>= 1; } return ret; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i = 0; i <n; i++) scanf("%d",&a[i]); sort(a,a+n); n = unique(a,a+n) - a; if (n == 0 || m == 0) { printf("0\n"); continue; } Mat tp = solve(); Mat tmp = pow_mat(tp,m-1); long long ans = 0; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) ans = (long long)(ans + tmp.s[i][j])%mod; printf("%I64d\n",ans); } } 主要部分: struct Matrix { LL m[55][55]; }; Matrix init; Matrix MatrixMul(Matrix a, Matrix b){ Matrix c; int i,j,k; for(i=0;i<N;i++){ for(j=0;j<N;j++){ c.m[i][j]=0; for(k=0;k<N;k++){ c.m[i][j]+=(a.m[i][k]*b.m[k][j]); c.m[i][j]%=kmod; } } } return c; } Matrix QuickPow(Matrix m,int p){ Matrix b; int i; memset(b.m,0,sizeof b.m); for(i=0;i<N;i++) b.m[i][i]=1; while(p){ if(p%2) b=MatrixMul(b,m); p/=2; m=MatrixMul(m,m); } return b; }