CodeForces - 697F:Legen... (AC自动机+矩阵)

Barney was hanging out with Nora for a while and now he thinks he may have feelings for her. Barney wants to send her a cheesy text message and wants to make her as happy as possible.

Initially, happiness level of Nora is 0. Nora loves some pickup lines like "I'm falling for you" and stuff. Totally, she knows n pickup lines, each consisting only of lowercase English letters, also some of them may be equal (in writing, but different in pronouncing or meaning though). Every time Nora sees i-th pickup line as a consecutive subsequence of Barney's text message her happiness level increases by ai. These substrings may overlap, for example, Nora will see the pickup line aa twice and the pickup line ab once in text message aaab.

Due to texting app limits, Barney's text may have up to l characters.

Barney asked you to help him make Nora as much happy as possible, it's gonna be legen...

Input

The first line of input contains two integers n and l (1 ≤ n ≤ 200, 1 ≤ l ≤ 1014) — the number of pickup lines and the maximum length of Barney's text.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 100), meaning that Nora's happiness level increases by ai after every time seeing i-th pickup line.

The next n lines contain the pickup lines. i-th of them contains a single string siconsisting of only English lowercase letter. Summary length of all pickup lines does not exceed 200.

All strings are not empty.

Output

Print the only integer — the maximum possible value of Nora's happiness level after reading Barney's text.

Examples

Input
3 6
3 2 1
heart
earth
art
Output
6
Input
3 6
3 2 8
heart
earth
art
Output
16

题意:现在有N个字符串,每个字符串有个价值,然后叫你写一个长度为L的字符串,其价值为所含子串的价值和。

思路:AC自动机+矩阵。以前的是求方案数,用矩阵加速累加即可。关键在于如何得到最大值:把矩阵的累加改为取max。

         要用-1去约束可不可以走到的位置。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=210;
int ch[maxn][26],End[maxn],fail[maxn];
int num[maxn],q[maxn],head,tail,cnt;
char c[maxn];
void insert(int opt)
{
    int Now=0; for(int i=1;c[i];i++){
        if(!ch[Now][c[i]-'a']) ch[Now][c[i]-'a']=++cnt;
        Now=ch[Now][c[i]-'a'];
    }   End[Now]+=num[opt];
}
void failbuild()
{
    for(int i=0;i<26;i++)
      if(ch[0][i]) q[++head]=ch[0][i];
    while(tail<head){
        int Now=q[++tail];
        End[Now]+=End[fail[Now]];
        for(int i=0;i<26;i++){
            if(ch[Now][i]) {
                q[++head]=ch[Now][i];
                fail[ch[Now][i]]=ch[fail[Now]][i];
            }
            else ch[Now][i]=ch[fail[Now]][i];
        }
    }
}
struct mat
{
    ll mp[maxn][maxn];
    mat(){}
    mat(ll x){for(int i=0;i<=cnt;i++) for(int j=0;j<=cnt;j++) mp[i][j]=x; }
    mat friend operator *(mat a,mat b){
        mat res(-1); 
        for(int k=0;k<=cnt;k++)
         for(int i=0;i<=cnt;i++)
          for(int j=0;j<=cnt;j++){
            if(a.mp[i][k]!=-1&&b.mp[k][j]!=-1) 
             res.mp[i][j]=max(res.mp[i][j],a.mp[i][k]+b.mp[k][j]);
        }return res;
    }
    mat friend operator ^(mat a,ll x){
        mat res(-1); res.mp[0][0]=0; 
        while(x){
            if(x&1) res=res*a;
            a=a*a;x>>=1;
        }return res;
    }
};
mat a;
void failmat()
{
    for(int i=0;i<=cnt;i++)
     for(int j=0;j<=cnt;j++)
      a.mp[i][j]=-1;
    for(int i=0;i<=cnt;i++){
        for(int j=0;j<26;j++)
        a.mp[i][ch[i][j]]=End[ch[i][j]];
    }
}
int main()
{
    int N,i,j; ll L,Max=0;
    scanf("%d%I64d",&N,&L);
    for(i=1;i<=N;i++) scanf("%d",&num[i]);
    for(i=1;i<=N;i++){
        scanf("%s",c+1);
        insert(i);
    }
    failbuild();
    failmat();
    mat ans=a^L;
    for(i=0;i<=cnt;i++)  Max=max(Max,ans.mp[0][i]);
    printf("%I64d\n",Max);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hua-dong/p/9250854.html