SPOJ 7758 Growing Strings

MGLAR10 - Growing Strings

Gene and Gina have a particular kind of farm. Instead of growing animals and vegetables, as it is usually the case in regular farms, they grow strings. A string is a sequence of characters.

Strings have the particularity that, as they grow, they add characters to the left and/or to the right of themselves, but they never lose characters, nor insert new characters in the middle.Gene and Gina have a collection of photos of some strings at di?erent times during their growth.

The problem is that the collection is not annotated, so they forgot to which string each photo belongs to. They want to put together a wall to illustrate strings growing procedures, but they

need your help to ?nd an appropriate sequence of photos.

Each photo illustrates a string. The sequence of photos must be such that if si comes immediately before si+1 in the sequence, then si+1 is a string that may have grown from si (i.e., si appears as a consecutive substring of si+1). Also, they do not want to use repeated pictures,so all strings in the sequence must be di?erent.

Given a set of strings representing all available photos, your job is to calculate the size of the largest sequence they can produce following the guidelines above.

Gene and Gina have a particular kind of farm. Instead of growing animals and vegetables, as it is usually the case in regular farms, they grow strings. A string is a sequence of characters. Strings have the particularity that, as they grow, they add characters to the left and/or to the right of themselves, but they never lose characters, nor insert new characters in the middle.

Gene and Gina have a collection of photos of some strings at di?erent times during their growth. The problem is that the collection is not annotated, so they forgot to which string each photo belongs to. They want to put together a wall to illustrate strings growing procedures, but they need your help to ?nd an appropriate sequence of photos.

Each photo illustrates a string. The sequence of photos must be such that if si comes immediately before si+1 in the sequence, then si+1 is a string that may have grown from si (i.e., si appears as a consecutive substring of si+1). Also, they do not want to use repeated pictures, so all strings in the sequence must be di?erent.

Given a set of strings representing all available photos, your job is to calculate the size of the largest sequence they can produce following the guidelines above.

Input

Each test case is given using several lines. The ?rst line contains an integer N representing the number of strings in the set (1 ≤ N ≤ 10^4). Each of the following N lines contains a di?erent non-empty string of at most 1000 lowercase letters of the English alphabet. Within each test case, the sum of the lengths of all strings is at most 10^6.

The last test case is followed by a line containing one zero.

Output

For each test case output a single line with a single integer representing the size of the largest sequence of photos that can be produced.

Sample

input6
plant
ant
cant
decant
deca
an
2
supercalifragilisticexpialidocious
rag
0

output4
2
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cstring>
using namespace std;
const int sigma_size=26;
const int N=1e4+5;
char s[1005];
struct Trie
{
    Trie* next[sigma_size];
    Trie* fail;
    int v,cnt,sum;
    Trie()
    {
        memset(next,0,sizeof(next));
        fail=0;
        cnt=sum=v=0;
    }
};
struct AhoCorasickAutomata
{
    Trie *root;
    AhoCorasickAutomata()
    {
        root=new Trie();
    }
    inline int idx(char c)
    {
        return c-‘a‘;
    }
    void _insert(char *s,int v)
    {
        int len=strlen(s);
        Trie* p=root;
        for(int i=0;i<len;i++)
        {
            int c=idx(s[i]);
            if(p->next[c]==0)
            {

                Trie* q=new Trie();
                p->next[c]=q;
            }
            p=p->next[c];
        }
        p->v=v,p->cnt++;
    }
    void getfail()
    {
        queue<Trie*>Q;
        root->fail=0;
        Q.push(root);
        while(!Q.empty())
        {
            Trie* u=Q.front();Q.pop();
            for(int i=0;i<sigma_size;i++)
                if(u->next[i])
                {
                    Trie* p=u->fail;
                    while(p&&!p->next[i])p=p->fail;
                    u->next[i]->fail=p?p->next[i]:root;
                    u->next[i]->sum=max(u->sum,u->next[i]->fail->sum)+u->next[i]->cnt;
                    Q.push(u->next[i]);
                }
        }
    }
};
int dfs(Trie* u,int ans)
{
    ans=max(ans,u->sum);
    for(int i=0;i<sigma_size;i++)
        if(u->next[i])
            ans=max(ans,dfs(u->next[i],ans));
    return ans;
}
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        AhoCorasickAutomata ac;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            ac._insert(s,i);
        }
        ac.getfail();
        printf("%d\n",dfs(ac.root,-1));
    }
    return 0;
}
时间: 2024-10-17 00:47:40

SPOJ 7758 Growing Strings的相关文章

SPOJ 7758. Growing Strings (ac自动机+dp)

题目大意: 给出了N个串.问最多有多少个串组成的序列,是可以由上一个串通过左右两边加字符构成的. 思路分析: 在trie上的dp 在建立自动机的时候,得到fail的同时,用dp记录这个串作为最后一个串所可以得到的最多的满足要求的串的数量. 那么 dp[i] = max(dp[i在trie上的的父亲节点],dp[i的fail节点] )+ 以i节点结尾的单词的数量,注意不是以i字符结尾. #include <cstdio> #include <iostream> #include &l

UVALive - 4811 Growing Strings (AC自动机+dp)

题目链接:UVALive - 4811 Growing Strings 题意: 给你n个字符串,问你最多能选出多少个字符串,使得s[i]是s[i+1]的子串. 题解: 先将所有的字符串插入AC自动机,将所有字符串按长度排序后,显然dp[i]=max{dp[j]}+1,其中s[j]是s[i]的子串.然后就完了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int

【SPOJ】MGLAR10 - Growing Strings

Gene and Gina have a particular kind of farm. Instead of growing animals and vegetables, as it is usually the case in regular farms, they grow strings. A string is a sequence of characters. Strings have the particularity that, as they grow, they add

AC自动机- 自我总结

AC自动机算法总结  No.1 What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一. 简单的说,KMP用来匹配一个模式串:但如果现在有多个模式串需要在同一篇文章中出现,现在就需要Aho-Corasick automaton算法了. 不要天真的以为AC自动机为auto-Accept,虽然他能让你AC一些题. No.2 My Understanding About Aho-Corasick automato

SPOJ:PATHETIC STRINGS(分配问题&amp;贪心)

Problem statement: A string is said to be “PATHETIC” if all the characters in it are repeated the same number of times. You are given a string of length n, what is the minimum number of changes required to make a string “PATHETIC”. The string has onl

BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster( 后缀数组 + 二分 + RMQ + 树状数组 )

全部串起来做SA, 在按字典序排序的后缀中, 包含每个询问串必定是1段连续的区间, 对每个询问串s二分+RMQ求出包含s的区间. 然后就是求区间的不同的数的个数(经典问题), sort queries + BIT 就行了.时间复杂度O(N log N). 速度垫底了QAQ 你们都会SAM.... ---------------------------------------------------------------------- #include<cmath> #include<c

【BZOJ2780】[Spoj]8093 Sevenk Love Oimaster 广义后缀自动机

[BZOJ2780][Spoj]8093 Sevenk Love Oimaster Description Oimaster and sevenk love each other.     But recently,sevenk heard that a girl named ChuYuXun was dating with oimaster.As a woman's nature, sevenk felt angry and began to check oimaster's online t

【SPOJ】1812. Longest Common Substring II(后缀自动机)

http://www.spoj.com/problems/LCS2/ 发现了我原来对sam的理解的一个坑233 本题容易看出就是将所有匹配长度记录在状态上然后取min后再对所有状态取max. 但是不要忘记了一点:更新parent树的祖先. 为什么呢?首先如果子树被匹配过了,那么长度一定大于任意祖先匹配的长度(甚至有些祖先匹配长度为0!为什么呢,因为我们在匹配的过程中,只是找到一个子串,可能还遗漏了祖先没有匹配到,这样导致了祖先的记录值为0,那么在对对应状态去min的时候会取到0,这样就wa了.而

SPOJ SUBLEX 7258. Lexicographical Substring Search

看起来像是普通的SAM+dfs...但SPOJ太慢了......倒腾了一个晚上不是WA 就是RE ..... 最后换SA写了...... Lexicographical Substring Search Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description Little Daniel loves to play wi