HDU 4436 str2int

str2int

Time Limit: 3000ms

Memory Limit: 131072KB

This problem will be judged on HDU. Original ID: 4436
64-bit integer IO format: %I64d      Java class name: Main

In this problem, you are given several strings that contain only digits from ‘0‘ to ‘9‘, inclusive.
An example is shown below.
101
123
The set S of strings is consists of the N strings given in the input file, and all the possible substrings of each one of them.
It‘s boring to manipulate strings, so you decide to convert strings in S into integers.
You can convert a string that contains only digits into a decimal integer, for example, you can convert "101" into 101, "01" into 1, et al.
If an integer occurs multiple times, you only keep one of them. 
For example, in the example shown above, all the integers are 1, 10, 101, 2, 3, 12, 23, 123.
Your task is to calculate the remainder of the sum of all the integers you get divided by 2012.

Input

There are no more than 20 test cases.
The test case starts by a line contains an positive integer N.
Next N lines each contains a string consists of one or more digits.
It‘s guaranteed that 1≤N≤10000 and the sum of the length of all the strings ≤100000.
The input is terminated by EOF.

Output

An integer between 0 and 2011, inclusive, for each test case.

Sample Input

5
101
123
09
000
1234567890

Sample Output

202

Source

2012 Asia Tianjin Regional Contest

解题:后缀自动机大法好

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int mod = 2012;
 4 const int maxn = 210001;
 5 struct node {
 6     int son[11],f,len;
 7     void init() {
 8         f = -1;
 9         len = 0;
10         memset(son,-1,sizeof son);
11     }
12 };
13 struct SAM {
14     node e[maxn<<1];
15     int tot,last;
16     int newnode(int len = 0) {
17         e[tot].init();
18         e[tot].len = len;
19         return tot++;
20     }
21     void init() {
22         tot = last = 0;
23         newnode(0);
24     }
25     void extend(int c) {
26         int p = last,np = newnode(e[p].len + 1);
27         while(p != -1 && e[p].son[c] == -1) {
28             e[p].son[c] = np;
29             p = e[p].f;
30         }
31         if(p == -1) e[np].f = 0;
32         else{
33             int q = e[p].son[c];
34             if(e[p].len + 1 == e[q].len) e[np].f = q;
35             else{
36                 int nq = newnode();
37                 e[nq] = e[q];
38                 e[nq].len = e[p].len + 1;
39                 e[np].f = e[q].f = nq;
40                 while(p != -1 && e[p].son[c] == q){
41                     e[p].son[c] = nq;
42                     p = e[p].f;
43                 }
44             }
45         }
46         last = np;
47     }
48 }sam;
49 char str[maxn];
50 int cnt[maxn<<1],c[maxn<<1],sum[maxn<<1],sa[maxn<<1];
51 int main() {
52     int n,len;
53     while(~scanf("%d",&n)){
54         sam.init();
55         for(int i = len = 0; i < n; ++i){
56             scanf("%s",str + len);
57             len = strlen(str);
58             if(i + 1 < n) str[len++] = ‘0‘ + 10;
59         }
60         for(int i = 0; i < len; ++i)
61             sam.extend(str[i] - ‘0‘);
62         memset(c,0,sizeof c);
63         memset(cnt,0,sizeof cnt);
64         memset(sum,0,sizeof sum);
65         for(int i = 0; i < sam.tot; ++i) c[sam.e[i].len]++;
66         for(int i = 1; i <= len; ++i) c[i] += c[i-1];
67         for(int i = sam.tot-1; i >= 0; --i) sa[--c[sam.e[i].len]] = i;
68         int ret = 0;
69         cnt[0] = 1;
70         for(int i = 0; i < sam.tot; ++i){
71             int x = sa[i];
72             for(int j = 0; j < 10; ++j){
73                 if(x == 0 && j == 0) continue;
74                 cnt[sam.e[x].son[j]] += cnt[x];
75                 sum[sam.e[x].son[j]] += sum[x]*10 + cnt[x]*j;
76                 cnt[sam.e[x].son[j]] %= mod;
77                 sum[sam.e[x].son[j]] %= mod;
78             }
79             ret = (ret + sum[x])%mod;
80         }
81         printf("%d\n",ret);
82     }
83     return 0;
84 }

时间: 2024-10-14 13:46:50

HDU 4436 str2int的相关文章

hdu 4436 str2int(后缀自动机)

题目链接:hdu 4436 str2int 题意: 给你n个字符串,每个字符串都是由数字构成,现在让你将这n个字符串所有的不重复子串构成的十进制数字加起来mod2012. 题解: 似乎这种不重复的子串问题,用后缀自动机都比较无脑搞. 首先将所有的串连起来,中间插个特殊字符,然后建立后缀自动机. 然后拓扑排序,从跟开始往下dp. sum[v]=Σ(sum[x]*10+cnt[x]*j),其中cnt[x]表示有多少条路径能到x这个节点,转移为cnt[v]=Σcnt[x] (x能转移到v),j为这个节

HDU 4436 str2int(后缀自动机)

[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4436 [题目大意] 给出一些字符串,由0~9组成,求出所有不同子串的和. [题解] 将所有字符串添加拼接符10连接在一起建立自动机, 从起点开始遍历所有节点,就能计算所有的子串和了.注意转移的时候只转移0到9节点. [代码] #include <cstdio> #include <cstring> #include <algorithm> #include <ve

字符串(多串后缀自动机):HDU 4436 str2int

str2int Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2082    Accepted Submission(s): 744 Problem Description In this problem, you are given several strings that contain only digits from '0'

【HDU 4436】 str2int (广义SAM)

str2int Problem Description In this problem, you are given several strings that contain only digits from '0' to '9', inclusive.An example is shown below.101123The set S of strings is consists of the N strings given in the input file, and all the poss

后缀自动机(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.

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include