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\n",ans);
81     }
82     return 0;
83 }
时间: 2024-08-27 05:57:33

UVA1673 str2int(SAM)的相关文章

后缀自动机(SAM)学习指南

*在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符串所有后缀的自动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 可以用 SAM 轻松水过,由此 SAM 流行了起来. 一般来说,能用后缀自动机解决的问题都可以用后缀数组解决.但是后缀自动机也拥有自己的优点. 1812.

后缀自己主动机(SAM)学习指南

*在学习后缀自己主动机之前须要熟练掌握WA自己主动机.RE自己主动机与TLE自己主动机* 什么是后缀自己主动机 后缀自己主动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造.可以接受一个字符串全部后缀的自己主动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 能够用 SAM 轻松水过.由此 SAM 流行了起来. 一般来说.能用后缀自己主动机解决的问题都能够用后缀数组解决.可是后缀自己

后缀自动机(SAM)

*在学习后缀自动机之前需要熟练掌握WA自动机.RE自动机与TLE自动机* 什么是后缀自动机 后缀自动机 Suffix Automaton (SAM) 是一个用 O(n) 的复杂度构造,能够接受一个字符串所有后缀的自动机. 它最早在陈立杰的 2012 年 noi 冬令营讲稿中提到. 在2013年的一场多校联合训练中,陈立杰出的 hdu 4622 可以用 SAM 轻松水过,由此 SAM 流行了起来. 一般来说,能用后缀自动机解决的问题都可以用后缀数组解决.但是后缀自动机也拥有自己的优点. 1812.

bzoj 3926 [Zjoi20150]诸神眷顾的幻想乡(SAM)

3926: [Zjoi20150]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 615  Solved: 369[Submit][Status][Discuss] Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常高兴啦. 这时幽香发现了一件非常有趣的事情,太阳花田有

bwa比对软件的使用以及其结果文件(sam)格式说明

一.bwa比对软件的使用 1.对参考基因组构建索引 bwa index -a bwtsw hg19.fa   #  -a 参数:is[默认] or bwtsw,即bwa构建索引的两种算法,两种算法都是基于BWT的(BWT search while the CIGAR string by Smith-Waterman alignment.).-a bwtsw对于短的参考序列是不工作的,必须要大于等于10Mb:-a is 不适用于大的参考序列,必须要小于等于2G: output:hg19.fa.am

后缀数组(SA)与后缀自动机(SAM)

定义 \(S\):需要处理的字符串,长度为 \(len\) \(suf_i\):字符串\(S\)中下标为 \(i \sim len\) 的连续子串(即后缀) \(rank_i\):\(suf_i\)在所有后缀中的排名 \(SA_i\):后缀数组,排名为\(i\)的后缀在原串中的位置,满足 \(suf_{SA_1} < suf_{SA_2} < \dots < suf_{SA_{len}}\),与 \(rank_i\) 为互逆运算 \(height_i\):高度数组,排名相邻的两个后缀的最

codevs 3160 最长公共子串(SAM)

3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Output Description 输出最长公共子串的长度 样例输入 Sample Input yeshowmuchiloveyoumydearmotherreallyicannotbelieveityeaphowmuchiloveyoumydearmother 样例输出 Sample Output 27

【BZOJ 3238】 3238: [Ahoi2013]差异(SAM)

3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3047  Solved: 1375 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N<=500000,S由小写英文字母组成 Source [分析] 这题先把sigma len 加上. 然后考虑一下减掉的是什么. 对于每个子

wenbao与后缀自动机(SAM)

引用大神模板 1 作者:后缀自动机·张 2 链接:https://zhuanlan.zhihu.com/p/25948077 3 来源:知乎 4 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 5 6 struct SAM{ 7 static const int maxn = 300010 * 2; 8 struct node{ 9 node*nxt[26],*fail; 10 int len; 11 }; 12 13 node*root;int cnt; 14 node