zoukankan      html  css  js  c++  java
  • 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);
         }
    }
  • 相关阅读:
    二叉排序树的建立_查找_插入_删除
    java学习书籍推荐
    Java之路——敬JAVA初学者(作者:MoMo)
    结构体的定义及应用
    java获取缓存通用类
    金额转换为自定义字符串
    WebApi接入Swagger
    webApi的控制台服务
    自动生成缓存Key值的CacheKeyHelper
    DictionaryHelper2
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8472662.html
Copyright © 2011-2022 走看看