• bzoj3277


    题解:

    后缀自动机

    然后抄了一发题解

    可以看看这个博客:http://blog.csdn.net/clover_hxy/article/details/53861268

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200005;
    typedef long long ll;
    int n,m,np,nq,p,q,cnt,root,last,len,sz,ch[N][20],fa[N];
    int size[N],l[N],nxt[N],a[N],now,pd[N],mark[N],v[N],pos[N];  
    int point[N],next[N],vi[N],tot,tt,head[N],nt[N];  
    ll c[N];
    char s[N];
    void add(int x,int y)
    {
        next[++tot]=point[x];
        point[x]=tot;
        vi[tot]=y;
    }
    void addfa(int x,int y)
    {
        nt[++tt]=head[x];
        head[x]=tt;
        v[tt]=y;
    }
    void extend(int x)
    {
        int c=a[x];
        p=last;
        np=++cnt;
        last=np;
        l[np]=l[p]+1;
        for (;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
        if (!p)fa[np]=root;
        else
         {
             q=ch[p][c];
             if (l[q]==l[p]+1)fa[np]=q;
             else
              {
                  nq=++cnt;
                  l[nq]=l[p]+1;
                  memcpy(ch[nq],ch[q],sizeof ch[nq]);
                  size[nq]=size[q];
                  nxt[nq]=nxt[q];
                  fa[nq]=fa[q];
                  fa[q]=fa[np]=nq;
                  for (;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
             }
         }
        add(now,np);
        for (;np;np=fa[np])
         if (nxt[np]!=now)
          {
              nxt[np]=now;
              size[np]++;
          } 
         else break;  
    }
    void dfs(int x)
    {
        c[x]+=c[fa[x]];
        for (int i=head[x];i;i=nt[i])dfs(v[i]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        root=++cnt;
        for (int i=1;i<=n;i++)
         {
             scanf("%s",s+1);
             last=root;
             len=strlen(s+1);
             now=i;
             for (int j=1;j<=len;j++)
              a[++sz]=s[j]-'a',extend(sz);
             mark[i]=sz;
         }
        for (int i=1;i<=cnt;i++)v[l[i]]++;
        for (int i=1;i<=cnt;i++)v[i]+=v[i-1];
        for (int i=1;i<=cnt;i++)pos[v[l[i]]--]=i;
        for (int i=1;i<=cnt;i++)
         {
             int t=pos[i];
             addfa(fa[t],t);
             if (size[t]>=m)c[t]=(ll)(l[t]-l[fa[t]]);
             else c[t]=0;
         } 
        c[1]=0;
        dfs(1);
        for (int i=1;i<=n;i++)
         {
             ll ans=0;
             for (int j=point[i];j;j=next[j])ans+=c[vi[j]];
             printf("%lld ",ans);
         }
    }
  • 相关阅读:
    线段树入门总结
    从零基础学三分查找
    Codeforces Beta Round #1 A,B,C
    isupper()函数
    matlab字符串操作总结
    hdu 4873 ZCC Loves Intersection(大数+概率)
    设计模式入门之桥接模式Bridge
    有关UIWebView的SSL总结
    vmware虚拟机上linux操作系统进行tty1~tty6切换方法和具体步骤
    Python BeautifulSoup4 使用指南
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8472662.html
Copyright © 2020-2023  润新知