【[USACO17DEC]Standing Out from the Herd】

题目

不会广义\(SAM\)

但信仰插入特殊字符就可以搞定一切了

我们先把所有的串搞在一起建出一个\(SAM\),记得在中间插入特殊字符

对于\(parent\)树上的一个节点,只有当其\(endpos\)集合中的所有元素都来自于同一个串的时候我们才对它进行统计

所以我们需要维护一个\(parent\)树上子树最大值和最小值,这样我们就能很快的判断这个\(endpos\)是否合法了

但是非常棘手的一类情况是我们插进去的特殊字符,显然\(SAM\)里有一些奇奇怪怪的子串中含有特殊字符

那也好办,我们存好每个串的起始位置只要那些没有跨越特殊字符的就好了

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 200005
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
struct E{int v,nxt;} e[maxn];
char S[maxn];
int m,n,lst=1,cnt=1,num;
int len[maxn],fa[maxn],son[maxn][27],mx[maxn],ml[maxn];
int f[maxn],head[maxn],d[maxn],Ans[maxn],li[maxn];
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
void dfs(int x) {
    for(re int i=head[x];i;i=e[i].nxt) 
        dfs(e[i].v),mx[x]=max(mx[e[i].v],mx[x]),ml[x]=min(ml[e[i].v],ml[x]),d[x]|=d[e[i].v];
}
inline void ins(int c,int o)
{
    int f=lst,p=++cnt; lst=p;
    len[p]=len[f]+1,mx[p]=ml[p]=o;
    if(c==26) d[p]=1;
    while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
    if(!f) {fa[p]=1;return;}
    int x=son[f][c];
    if(len[f]+1==len[x]) {fa[p]=x;return;}
    int y=++cnt;
    len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
    for(re int i=0;i<27;i++) son[y][i]=son[x][i];
    while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
}
int main()
{
    memset(ml,20,sizeof(ml));
    scanf("%d",&m);
    for(re int i=1;i<=m;i++)
    {
        scanf("%s",S+1);
        int len=strlen(S+1);li[i]=n+1;
        for(re int j=1;j<=len;j++) ins(S[j]-'a',++n),f[n]=i;
        ins(26,++n);
    }
    for(re int i=2;i<=cnt;i++) add(fa[i],i);
    dfs(1);
    for(re int i=2;i<=cnt;i++)
    {
        if(d[i]) continue;
        if(f[mx[i]]!=f[ml[i]]) continue;
        int minlen=len[fa[i]]+1;
        if(f[mx[i]-minlen+1]!=f[mx[i]]) continue;
        if(f[mx[i]-len[i]+1]==f[mx[i]]) Ans[f[mx[i]]]+=len[i]-len[fa[i]];
            else Ans[f[mx[i]]]+=mx[i]-li[f[mx[i]]]-minlen+2;
    }
    for(re int i=1;i<=m;i++) printf("%d\n",Ans[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/asuldb/p/10249310.html