[2018.07.17 T1] 字符串最大值

暂无连接

字符串最大值

【问题描述】

少年易学老难成,一寸光阴不可轻。

一个字符串的前缀是指包含该字符第一个字母的连续子串,例如: a b c d 的所有前缀为 a , a b , a b c , a b c d

给出一个字符串 S ,求其所有前缀中,字符长度与出现次数的乘积的最大值。

例如: S =" a b a b a b a " 所有的前缀如下:

" a " , 长度与出现次数的乘积 1 4 = 4
" a b " ,长度与出现次数的乘积 2 3 = 6
" a b a " , 长度与出现次数的乘积 3 3 = 9
" a b a b " , 长度与出现次数的乘积 4 2 = 8
" a b a b a " , 长度与出现次数的乘积 5 2 = 10
" a b a b a b " , 长度与出现次数的乘积 6 1 = 6
" a b a b a b a " , 长度与出现次数的乘积 7 1 = 7

其中”ababa”出现了 2 次,二者的乘积为 10 ,是所有前缀中最大的。

【输入格式】

输入字符串 T T 中的所有字符均为小写英文字母。

【输出格式】

输出所有前缀中字符长度与出现次数的乘积的最大值。

【输入样例】

abababa

【输出样例】

10

【样例说明】

a b a b a 出现了两次

【数据范围】

20 % 的输入数据 : 1 <= L <= 100

40 % 的输入数据 : 1 <= L <= 1000

50 % 的输入数据 : 1 <= L <= 5000

100 % 的输入数据 : 1 <= L <= 1000000 L T 的长度。

数据非常有梯度。

题解

AC自动机天下第一,KMP辣鸡。

直接插入原串再用原串匹配一下,匹配完后拓扑递推一下即可统计答案。

但是裸的 A C 自动机会 M L E ,因为 T r i e 退化成了一条链,所以就不用开 M × 26 了。

代码
#include<bits/stdc++.h>
using namespace std;
const int M=1e6+5;
char ch[M];
int len,tot,t[M],fail[M],son[M],nxt[M];
queue<int>dui;
void in(){scanf("%s",ch+1);}
void ins()
{
    int v=0,s;
    for(int i=1;i<=len;++i)
    {
        s=ch[i]-'a';
        if(!son[v])son[v]=++tot;
        nxt[v]=s,v=son[v];
    }
}
void bfs()
{
    int v,p;dui.push(0);
    while(!dui.empty())
    {
        v=dui.front();dui.pop();
        for(int i=0;i<26;++i)
        {
            if(nxt[v]!=i)continue;
            if(!v)fail[son[v]]=0;
            else
            {
                for(p=fail[v];~p;p=fail[p])if(nxt[p]==i){fail[son[v]]=son[p];break;}
                if(p==-1)fail[son[v]]=0;
            }
            if(son[v])dui.push(son[v]);
        }
    }
}
void cmp()
{
    int v=0,s,p;
    for(int i=1;i<=len;++i)
    {
        s=ch[i]-'a';
        while(v&&nxt[v]!=s)v=fail[v];
        if(nxt[v]==s)v=son[v];
        ++t[v];
    }
}
void ac()
{
    len=strlen(ch+1);fail[0]=-1;
    ins();bfs();cmp();long long ans=0;
    for(int i=len;i>=1;--i)t[fail[i]]+=t[i],ans=max(ans,1ll*i*t[i]);
    printf("%lld",ans);
}
int main(){in();ac();}

猜你喜欢

转载自blog.csdn.net/shadypi/article/details/81087674
t1