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. JavaScript 笔记总结

    一.js的简介  1.js是什么 js是可以嵌入到html中,是 基于对象 和 事件驱动 的 脚本语言 特点: (1)交互性 (2)安全性:js不能访问本地磁盘 (3)跨平台:浏览器中都具备js解析器 ...

  2. 协议类接口 - UART

    一.何为协议类接口? 双方约定信号的协议和满足时序要求. 二.UART如何传数据 通用异步收发器简称 UART,即“Universal Asynchronous Receiver Transmitte ...

  3. SecureCRT 个人使用爱好配置。

    1.设置默认启动会话设置. 2.设置执行 ls命令显示文件夹,各种文件,不同的对比颜色 2.1 设置前: 2.2 设置后: 3. 如果出现会话框中文乱码 ,设置以下选项 4 . 更改 命令 ls -a ...

  4. rest_framework -- 认证组件

    #####认证组件##### 一.认证是什么就不说了,某些网页必须是用户登陆之后,才能访问的,所以这时候就需要用上认证组件. 你不用rest_framework的认证组件也行,这种认证的话,完全可以自 ...

  5. #leetcode刷题之路29- 两数相除

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符.返回被除数 dividend 除以除数 divisor 得到的商. 示例 1:输入: ...

  6. ABAP术语-Purchase Order

    Purchase Order 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/07/1094717.html Request or instr ...

  7. oracle中connect by语句的优化

    很多应用中都会有类似组织机构的表,组织机构的表又通常是典型的层次结构(没有循环节点).于是通过组织控制数据权限的时候,许多人都喜欢通过connect by获得组织信息,然后再过滤目标数据. 在有些情况 ...

  8. HTTP状态保持的原理

    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied) ...

  9. 爬虫——Selenium与PhantomJS

    Selenium Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同的是Selenium可以直接运行在浏览器上, ...

  10. Linux入门-第四周

    1.查找/var目录下不属于root.lp.gdm的所有文件 find命令:实时查找工具,通过指定路径完成文件查找,其特点查找速度略慢,可以精确查找,实时查找,可以只搜索用户具备读取和执行权限的目录 ...