• UVA1673 str2int(SAM)


    【题目链接】

        http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51267

    【题意】

        给定n个字符串,计算所有忽略前导0的子串形成的不重整数之和。

    【思路】

        既然是处理子串问题,我们可以合并串之后构造一个SAM。

        SAM的性质:结点u代表的字符串集是从根到u路径上的所有结点代表的字符串集之并,结点u所代表的字符串集为最长串的所有子串。

        记cnt[u]为状态u代表的字符串个数,sum[u]代表状态u代表的字符串对应的数之和。

        拓扑排序后,设p为当前结点,trans(p,j)为np,则有:

            cnt[np]+=cnt[p]

           sum[np]+=sum[p]*10+cnt[p]*j

        不走$边,第一次不走0边。

    【代码】

     1 #include<set>
     2 #include<cmath>
     3 #include<queue>
     4 #include<vector>
     5 #include<cstdio>
     6 #include<cstring>
     7 #include<iostream>
     8 #include<algorithm>
     9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
    10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
    11 using namespace std;
    12 
    13 typedef long long ll;
    14 const int N = 2e5+10;
    15 const int MOD = 2012;
    16 
    17 int n,len;
    18 char s[N];
    19 int sum[N],cnt[N];
    20 int sz,last,fa[N],ch[N][11],l[N],c[N],b[N];
    21 
    22 void add(int c)
    23 {
    24     int p=last,np=++sz; last=np;
    25     l[np]=l[p]+1;
    26     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    27     if(!p) fa[np]=1;
    28     else {
    29         int q=ch[p][c];
    30         if(l[q]==l[p]+1) fa[np]=q;
    31         else {
    32             int nq=++sz; l[nq]=l[p]+1;
    33             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    34             fa[nq]=fa[q];
    35             fa[q]=fa[np]=nq;
    36             for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq; 
    37         }
    38     }
    39 }
    40 void init()
    41 {
    42     sz=last=1;
    43     len=0;
    44     memset(sum,0,sizeof(sum));
    45     memset(cnt,0,sizeof(cnt));
    46     memset(ch,0,sizeof(ch));
    47     memset(c,0,sizeof(c));
    48     memset(fa,0,sizeof(fa));
    49     memset(l,0,sizeof(l));
    50 }
    51 int main()
    52 {
    53     while(scanf("%d",&n)==1) 
    54     {
    55         init();
    56         FOR(i,1,n) {
    57             scanf("%s",s);
    58             if(i!=1) add(10),len++;
    59             for(int j=0;s[j];j++)
    60                 add(s[j]-'0'),len++;
    61         }
    62         FOR(i,1,sz) c[l[i]]++;
    63         FOR(i,1,len) c[i]+=c[i-1];
    64         FOR(i,1,sz) b[c[l[i]]--]=i; 
    65     
    66         int ans=0;
    67         cnt[1]=1;
    68         FOR(i,1,sz) {
    69             int p=b[i];
    70             for(int j=0;j<10;j++) {
    71                 if(i==1&&j==0) continue;
    72                 if(ch[p][j]) {
    73                     int np=ch[p][j];
    74                     cnt[np]=(cnt[np]+cnt[p])%MOD;
    75                     sum[np]=(sum[np]+sum[p]*10+cnt[p]*j)%MOD;
    76                 }
    77             }
    78             ans=(ans+sum[p])%MOD;
    79         }
    80         printf("%d
    ",ans);
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    MYSQL索引
    列表里重复次数最多的元素
    python学习笔记
    Spark 扫描 HDFS lzo/gz/orc异常压缩文件
    Yarn RM写ZNode超数据量限制bug修复
    Spark HistoryServer日志解析&清理异常
    【Yarn源码分析】Container启动流程源码分析
    Yarn NodeManager总体架构
    【Yarn源码分析】ApplicationMaster源码分析
    【Yarn源码分析】FairScheduler资源调度
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5289228.html
Copyright © 2020-2023  润新知