考研路茫茫——单词情结
题意:
和上一题基本差不多
比较坑的是,矩阵快速幂的时候m+1了,会爆int,所以要用long long
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ull unsigned long long 4 #define CLR(m,a) memset(m,a,sizeof(m)) 5 const int maxnode=35; 6 const int sigma=26; 7 8 struct Matrix 9 { 10 ull n,m[maxnode<<1][maxnode<<1]; 11 void init(ull sz) 12 { 13 n=sz; 14 CLR(m,0); 15 } 16 Matrix(ull sz){init(sz);} 17 void setE() 18 { 19 for(int i=0;i<n;i++) m[i][i]=1; 20 } 21 Matrix operator *(const Matrix &a) 22 { 23 Matrix ans(n); 24 for(int k=0;k<n;k++) 25 for(int i=0;i<n;i++) 26 for(int j=0;j<n;j++) 27 ans.m[i][j]=ans.m[i][j]+m[i][k]*a.m[k][j]; 28 return ans; 29 } 30 }; 31 32 struct AC 33 { 34 int ch[maxnode][sigma],f[maxnode]; 35 int match[maxnode]; 36 int sz; 37 38 void init() 39 { 40 CLR(ch[0],0); 41 CLR(match,0); 42 sz=1; 43 } 44 int idx(char c){return c-'a';} 45 void inser(char *s) 46 { 47 int u=0,n=strlen(s); 48 for(int i=0;i<n;i++){ 49 int c=idx(s[i]); 50 if(!ch[u][c]){ 51 CLR(ch[sz],0); 52 ch[u][c]=sz++; 53 } 54 u=ch[u][c]; 55 } 56 match[u]=1; 57 } 58 void getfail() 59 { 60 queue<int> q; 61 f[0]=0; 62 for(int c=0;c<sigma;c++){ 63 int u=ch[0][c]; 64 if(u){ 65 q.push(u); 66 f[u]=0; 67 } 68 } 69 while(!q.empty()){ 70 int r=q.front(); 71 q.pop(); 72 for(int c=0;c<sigma;c++){ 73 int u=ch[r][c]; 74 if(!u){ch[r][c]=ch[f[r]][c];continue;} 75 q.push(u); 76 int v=f[r]; 77 while(v&&!ch[v][c]) v=f[v]; 78 f[u]=ch[v][c]; 79 match[u]|=match[f[u]]; 80 } 81 } 82 } 83 ull solve(ull m) 84 { 85 int tot=sz*2; 86 Matrix a(tot),b(tot); 87 for(int i=0;i<sz;i++) 88 for(int j=0;j<sigma;j++){ 89 if(match[i]||match[ch[i][j]]) continue; 90 a.m[i][ch[i][j]]++; 91 } 92 for(int i=0;i<sz;i++) a.m[i][i+sz]=1; //构造矩阵这里wa了几次。。。 93 for(int i=sz;i<tot;i++) a.m[i][i]=1; 94 b.setE(); 95 ull t=m; 96 while(t){ 97 if(t&1) b=b*a; 98 t>>=1; 99 a=a*a; 100 } 101 ull ans1=0; 102 for(int i=sz;i<tot;i++) 103 ans1=ans1+b.m[0][i]; 104 ans1--; 105 106 Matrix c(2),d(2); 107 d.setE(); 108 c.m[0][0]=26;c.m[0][1]=c.m[1][1]=1; 109 while(m){ 110 if(m&1) d=d*c; 111 m>>=1; 112 c=c*c; 113 } 114 ull ans2=d.m[0][1]-1; 115 return ans2-ans1; 116 } 117 }; 118 AC ac; 119 int main() 120 { 121 ull n,m; 122 char s[10]; 123 while(scanf("%llu%llu",&n,&m)!=EOF){ 124 ac.init(); 125 for(int i=0;i<n;i++){ 126 scanf("%s",s); 127 ac.inser(s); 128 } 129 ac.getfail(); 130 printf("%llu ",ac.solve(m+1)); 131 } 132 }