AC自动机上的倍增弗洛伊德
调了好长时间才发现size开小了。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
using namespace std;
#define ll long long
char c;
bool flag;
inline void read(ll &a)
{a=0;do c=getchar();while((c<'0'||c>'9')&&c!='-');c=c=='-'?flag=true,getchar():c;while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();a=flag?flag=false,-a:a;}
inline ll Max(ll &a,ll b){return a>b?a:a=b;}
inline ll Min(ll &a,ll b){return a<b?a:a=b;}
inline ll min(ll a,ll b){return a<b?a:b;}
inline ll max(ll a,ll b){return a>b?a:b;}
inline ll abs(ll a){return a>0?a:-a;}
struct A
{
int x,y;
ll a[201][201];
A(){}
A(int x,int y):x(x),y(y){memset(a,-1,sizeof(a));}
//ll *operator [](ll x){return a[x];}
void In(){for(int i=0;i<=200;i++)a[i][i]=0;}
A operator *(A b)
{
A c(x,b.y);
for(int k=0;k<=y;k++)
for(int i=0;i<=x;i++)
if(~a[i][k])for(int j=0;j<=b.y;j++)
if(~b.a[k][j])
{
if(i==13&&j==11&&k==12)
i++,i--;
Max(c.a[i][j],a[i][k]+b.a[k][j]);
}
return c;
}
};
A Pow(A x,ll t)
{
A res(x.x,x.y);
res.In();
for(t;t;t>>=1,x=x*x)
if(t&1)
res=res*x;
return res;
}
struct Node
{
int no;
Node *ch[27],*last[27],*f;
int Val;
Node(){memset(ch,0,sizeof(ch));Val=no=0;}
Node(int no):no(no){memset(ch,0,sizeof(ch));Val=0;}
}*Root=new Node;
char S[301];
int size;
ll Data[301];
inline void Add(int i)
{
scanf("%s",S+1);
int n=strlen(S+1);
Node *tp=Root;
for(int i=1;i<=n;tp=tp->ch[S[i++]-'a'])
if(!tp->ch[S[i]-'a']){tp->ch[S[i]-'a']=new Node(++size);}
tp->Val+=Data[i];
}
queue<Node*>Q;
inline void BFS()
{
for(int i=0;i<=26;i++)
if(Root->ch[i])
Q.push(Root->ch[i]),Root->ch[i]->f=Root,Root->last[i]=Root->ch[i];
else Root->last[i]=Root;
while(!Q.empty())
{
Node *u=Q.front();Q.pop();
if(u!=NULL)
{
Node *T=u;
u->Val+=u->f->Val;
for(int i=0;i<=26;i++)
if(!u->ch[i])
u->last[i]=u->f->last[i];
else
u->ch[i]->f=u->f->last[i],Q.push(u->last[i]=u->ch[i]);
}
}
}
A Dp;
void DFS(Node *Cur)
{
if(!Cur)return;
for(int i=0;i<27;i++)
DFS(Cur->ch[i]);
for(int i=0;i<27;i++)
if(Cur->last[i])
Max(Dp.a[Cur->last[i]->no][Cur->no],Cur->last[i]->Val);
}
int main()
{
ll n,l;
read(n),read(l);
for(int i=1;i<=n;i++)read(Data[i]);
for(int i=1;i<=n;i++)
Add(i);
BFS();
Dp=A(size,size);
DFS(Root);
Dp=Pow(Dp,l);
A ans(size,1);
ans.a[0][0]=0;
ans=Dp*ans;
ll Aa=-1;
for(int i=0;i<=size;i++)
Max(Aa,ans.a[i][0]);
cout<<Aa<<endl;
return 0;
}