Problem Description
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.
 
题目大意:计算n个串的所有子串(重复的算一个)的和,结果求余2012。
思路:把n个字符串用一个奇怪的东东(比如10)连起来,建一个后缀自动机。
由于在后缀自动机上,每一条路径到一个点,都唯一代表着一个字符串,所以重复什么的就没有了。
然后后缀自动机是一个DAG,随便搞搞就能做了。
PS:对后缀自动机熟悉的话,这题还是挺水的,是当时后缀自动机还不普及的缘故么。
 
代码(406MS):
 #include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std; const int MAXN = + ;
const int MOD = ;
char buf[MAXN];
struct State {
State *fail, *go[];
int val, dp, cnt;
bool mark;
/*
State() :
fail(0), val(0) {
memset(go, 0, sizeof go);
}*/
}*root, *last;
State statePool[MAXN * ], *cur; void init() {
memset(statePool, , sizeof(statePool));
cur = statePool;
root = last = cur++;
} void extend(int w) {
State *p = last, *np = cur++;
np->val = p->val + ;
while (p && !p->go[w])
p->go[w] = np, p = p->fail;
if (!p) np->fail = root;
else {
State*q = p->go[w];
if (p->val + == q->val) np->fail = q;
else {
State *nq = cur++;
memcpy(nq->go, q->go, sizeof q->go);
nq->val = p->val + ;
nq->fail = q->fail;
q->fail = nq;
np->fail = nq;
while (p && p->go[w] == q)
p->go[w] = nq, p = p->fail;
}
}
last = np;
} inline void update_add(int &a, const int &b) {
a = (a + b) % MOD;
} struct Node {
State *p;
bool operator < (const Node &rhs) const {
return p->val < rhs.p->val;
}
} a[MAXN * ]; int main() {
int n;
while(scanf("%d", &n) != EOF) {
init();
for(int i = ; i <= n; ++i) {
scanf("%s", buf);
for(char *pt = buf; *pt; ++pt)
extend(*pt - '');
extend();
}
int m = , ans = ;
for(State *p = statePool; p != cur; ++p) a[m++].p = p;
sort(a, a + m);
root->cnt = ;
for(int i = ; i < m; ++i) {
State *pt = a[i].p;
if(pt == root->go[] || pt->mark) continue;
update_add(ans, pt->dp);
for(int j = ; j < ; ++j) {
if(!pt->go[j]) continue;
update_add(pt->go[j]->dp, * pt->dp + pt->cnt * j);
update_add(pt->go[j]->cnt, pt->cnt);
}
if(pt->go[]) pt->go[]->mark = true;
}
printf("%d\n", ans);
}
}

HDU 4436 str2int(后缀自动机)(2012 Asia Tianjin Regional Contest)的更多相关文章

  1. HDU-4432-Sum of divisors ( 2012 Asia Tianjin Regional Contest )

    Sum of divisors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. HDU 4433 locker 2012 Asia Tianjin Regional Contest 减少国家DP

    意甲冠军:给定的长度可达1000数的顺序,图像password像锁.可以上下滑动,同时会0-9周期. 每个操作.最多三个数字连续操作.现在给出的起始序列和靶序列,获得操作的最小数量,从起始序列与靶序列 ...

  3. HDU 4441 Queue Sequence(优先队列+Treap树)(2012 Asia Tianjin Regional Contest)

    Problem Description There's a queue obeying the first in first out rule. Each time you can either pu ...

  4. HDU 4433 locker(DP)(2012 Asia Tianjin Regional Contest)

    Problem Description A password locker with N digits, each digit can be rotated to 0-9 circularly.You ...

  5. HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)

    Problem Description Japanese Mahjong is a four-player game. The game needs four people to sit around ...

  6. str2int HDU - 4436 (后缀自动机)

    str2int \[ Time Limit: 3000 ms\quad Memory Limit: 131072 kB \] 题意 给出 \(n\) 个串,求出这 \(n\) 个串所有子串代表的数字的 ...

  7. HDU 3721 Building Roads (2010 Asia Tianjin Regional Contest) - from lanshui_Yang

    感慨一下,区域赛的题目果然很费脑啊!!不过确实是一道不可多得的好题目!! 题目大意:给你一棵有n个节点的树,让你移动树中一条边的位置,即将这条边连接到任意两个顶点(边的大小不变),要求使得到的新树的直 ...

  8. HDU 3726 Graph and Queries(平衡二叉树)(2010 Asia Tianjin Regional Contest)

    Description You are given an undirected graph with N vertexes and M edges. Every vertex in this grap ...

  9. HDU 4468 Spy(KMP+贪心)(2012 Asia Chengdu Regional Contest)

    Description “Be subtle! Be subtle! And use your spies for every kind of business. ”― Sun Tzu“A spy w ...

随机推荐

  1. Viewpager实现今日头条顶部导航的功能

    利用简单的Textview 和Viewpager实现滑动.点击换页的效果,效果图如下: 先上布局文件代码: <?xml version="1.0" encoding=&quo ...

  2. 使用第三方《UITableView+FDTemplateLayoutCell》自动计算UITableViewCell高度(Masonry约束)

    直接上代码: 1:先自定义cell .h文件中 #import <UIKit/UIKit.h> #import "LBDNewMsgListModel.h" #impo ...

  3. 【PTA 天梯赛训练】QQ帐户的申请与登陆(散列+set模拟)

    实现QQ新帐户申请和老帐户登陆的简化版功能.最大挑战是:据说现在的QQ号码已经有10位数了. 输入格式: 输入首先给出一个正整数N(≤10^5),随后给出N行指令.每行指令的格式为:“命令符(空格)Q ...

  4. zabbix service安装配置

    1.安装时间同步 yum -y install ntpdate systemctl start ntpdate.service systemctl enable ntpdate.service 2.安 ...

  5. Sonarqube中文插件-Linux[20180105]

    前言     上次安装了Sonarqube英文版使用起来不方便,这次为Sonarqube安装中文插件. 前期准备:     软件下载: https://github.com/SonarQubeComm ...

  6. Python学习手册之Python异常和文件

    在上一篇文章中,我们介绍了 Python 的函数和模块,现在我们介绍 Python 中的异常和文件. 查看上一篇文章请点击:https://www.cnblogs.com/dustman/p/9963 ...

  7. PHP json_decode返回null解析失败原因

    在PHP5.4之前 json_decode函数有两个参数json_decode有两个参数,第一个是待解析的字符串,第二个是是否解析为Array json_decode要求的字符串比较严格:(1)使用U ...

  8. ADB工具的安装

    1.Windows ADB工具下载地址: https://developer.android.google.cn/studio/releases/platform-tools ADB工具官网教程: h ...

  9. JAVA反射之 Field (属性)

    主要方法: public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName ...

  10. Quartz,启动不立即执行问题

    我的Quartz 是2.2版本, 在java程序中写了两个加入计划方法 //// 添加简单计划任务 author:iresearch.com.cn -- jackical public static ...