zoukankan      html  css  js  c++  java
  • hihocoder #1457 : 后缀自动机四·重复旋律7

    题意:给定 (n) 个字符串 (S_{1cdots n}) ,求所有不同的子串的“和”(也就是把串看成数字,在十进制下的求和,允许有前导0)。答案有可能很大,我们需要对 (10^9 + 7) 取模。

    (SAM)

    把所有串用间隔字符拼起来,建出 (SAM) ,然后在上面 bfs ,求出每个点的答案。注意我们要减去不合法的转移,即跨越间隔字符的转移。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
      register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
      do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
    } const int N=2000010,M=1000000007;
    int n,lst=1,tot=1,anss;
    int fa[N],c[N][11],len[N],sz[N],sum[N],in[N],ans[N];
    char s[N];
    inline void add(int ch) {
      R p=lst,np=lst=++tot;
      len[np]=len[p]+1;
      for(;p&&!c[p][ch];p=fa[p]) c[p][ch]=np;
      if(!p) fa[np]=1;
      else {
        R q=c[p][ch];
        if(len[q]==len[p]+1) fa[np]=q;
        else {
          R nq=++tot;
          memcpy(c[nq],c[q],11<<2);
          fa[nq]=fa[q],len[nq]=len[p]+1;
          fa[np]=fa[q]=nq;
          for(;p&&c[p][ch]==q;p=fa[p]) c[p][ch]=nq;
        }
      }
    }
    queue<int> q;
    inline void main() {
      n=g(); 
      for(R i=1,len;i<=n;++i) {
        scanf("%s",s),len=strlen(s);
        for(R i=0;i<len;++i) add(s[i]-48); 
        add(10);
      }
      for(R i=1;i<=tot;++i) 
        for(R ch=0;ch<=10;++ch) 
          ++in[c[i][ch]];
      q.push(1);
      while(q.size()) {
        R u=q.front(); q.pop();
        R l=1;
        if(u!=1) l=len[u]-len[fa[u]];  
        for(R i=0;i<=10;++i) if(c[u][i]) {
          R v=c[u][i];
          if(v) {
            if(i!=10)
              ans[v]=(ans[v]+ans[u]*10ll+1ll*(l-sum[u]+M)*i)%M,
              sum[v]+=sum[u];
            else sum[v]+=l;
          } if(--in[v]==0) q.push(v);
        }
      }
      for(R i=1;i<=tot;++i) anss=(anss+ans[i])%M;
      printf("%d
    ",anss);
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2020.01.10

  • 相关阅读:
    吊打996,来了?!
    微软开源浏览器自动化工具Playwright for Python(附源码)
    从0到1开始建设安全测试体系
    网友爆料vivo将取消大小周,不降薪,官方证实消息属实
    认识了一个在华为任职的50岁程序员!
    漫画:什么是自动驾驶?
    中国十大杰出人物
    最难调试修复的 bug 是怎样的?
    “十年不升职多得是,四年算什么”
    appium+pytest实现APP并发测试
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12177414.html
Copyright © 2011-2022 走看看