内网传送门
A
C
AC
AC自动机+矩阵优化
D
P
DP
DP
初始化的时候,
m
a
t
r
i
x
matrix
matrix里面不能写
f
o
r
(
i
n
t
i
=
0
;
i
<
=
t
o
t
;
+
+
i
)
for(int\ i=0;i<=tot;++i)
for(int i=0;i<=tot;++i)
因为这时候
t
o
t
tot
tot为
0
0
0。(o皿o)。
每个点要加上它
f
a
i
l
fail
fail链指向的点的贡献,因为出现多次就要算多次。
#include<bits/stdc++.h>
#define re register
#define cs const
#define ll long long
cs int N=205,M=105,alpha=26;cs ll oo=1e9;
int m,tot=0;char s[N];ll n,value[M],ans=0;
struct trie{int son[alpha],fail;ll val;}a[N];
struct matrix{
ll a[N][N];
matrix(ll t=-oo){
for(int i=0;i<N;++i)
for(int j=0;j<N;++j) a[i][j]=-oo;
for(int i=0;i<N;++i) a[i][i]=t;
}
friend inline matrix operator*(cs matrix &a,cs matrix &b){
matrix c;
for(int i=0;i<=tot;++i)
for(int k=0;k<=tot;++k)
for(int j=0;j<=tot;++j)
c.a[i][j]=std::max(c.a[i][j],a.a[i][k]+b.a[k][j]);
return c;
}
friend inline matrix operator^(matrix a,ll b){
matrix c(0);
for(;b;b>>=1,a=a*a) if(b&1) c=c*a;
return c;
}
}A;
inline void insert(char *s,ll val){
int now=0,len=strlen(s);
for(int re i=0,v;i<len;++i){
v=s[i]-'a';
if(!a[now].son[v]) a[now].son[v]=++tot;
now=a[now].son[v];
}a[now].val+=val;
}
inline void getfail(){
std::queue<int> Q;
for(int re i=0,v;i<alpha;++i)
if(v=a[0].son[i]) a[v].fail=0,Q.push(v);
while(!Q.empty()){
int u=Q.front();Q.pop();
a[u].val+=a[a[u].fail].val;
for(int i=0,v;i<alpha;++i){
if(v=a[u].son[i]) a[v].fail=a[a[u].fail].son[i],Q.push(v);
else a[u].son[i]=a[a[u].fail].son[i];
}
}
}
inline void build_matrix(){
for(int i=0;i<=tot;++i)
for(int j=0,v;j<alpha;++j)
v=a[i].son[j],A.a[i][v]=a[v].val;
}
int main(){
// freopen("4750.in","r",stdin);
scanf("%lld%d",&n,&m);
for(int i=1;i<=m;++i) scanf("%lld",value+i);
for(int i=1;i<=m;++i) scanf("%s",s),insert(s,value[i]);
getfail(),build_matrix(),A=A^n;
for(int i=0;i<=tot;++i) ans=std::max(ans,A.a[0][i]);
printf("%lld\n",ans);
}