题意:给n个数字串,求它们的所有不包含前导0的不同子串的值之和

思路:把数字串拼接在一起,构造SAM,然后以每个状态的长度len作为特征值从小到大排序,从前往后处理每个状态,相当于按拓扑序在图上合并计算答案。

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define pb(x) push_back(x)
#define mp(x, y) make_pair(x, y)
#define all(a) (a).begin(), (a).end()
#define mset(a, x) memset(a, x, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(b))
#define cas() int T, cas = 0; cin >> T; while (T --)
template<typename T>bool umax(T&a, const T&b){return a<b?(a=b,true):false;}
template<typename T>bool umin(T&a, const T&b){return b<a?(a=b,true):false;}
typedef long long ll;
typedef pair<int, int> pii; #ifndef ONLINE_JUDGE
#include "local.h"
#endif const int mod = 2012; const int N = 2e5; class SAM {
public:
void init() {
memset(node, 0, sizeof(node));
sz = last = 0;
node[0].len = 0;
node[0].link = -1;
sz ++;
}
void add(char c) {
int cur = sz ++;
node[cur].len = node[last].len + 1;
int p;
for (p = last; ~p && !node[p].next[c]; p = node[p].link) {
node[p].next[c] = cur;
}
if (p == -1) node[cur].link = 0;
else {
int q = node[p].next[c];
if (node[p].len + 1 == node[q].len) node[cur].link = q;
else {
int clone = sz ++;
node[clone] = node[q];
node[clone].len = node[p].len + 1;
for (; ~p && node[p].next[c] == q; p = node[p].link) {
node[p].next[c] = clone;
}
node[q].link = node[cur].link = clone;
}
}
last = cur;
}
int c[N << 1], p[N << 1];
int getAns() {
mset(c, 0);
for (int i = 0; i < sz; i ++) c[node[i].len] ++;
for (int i = 1; i <= sz; i ++) c[i] += c[i - 1];
for (int i = 0; i < sz; i ++) p[-- c[node[i].len]] = i;
int ans = 0;
node[0].cnt = 1;
for (int i = 0; i < sz; i ++) {
int cur = p[i];
for (int j = 0; j < 10; j ++) {
if (!cur && !j || !node[cur].next[j]) continue;
int next = node[cur].next[j];
node[next].sum = (node[next].sum + node[cur].sum * 10 + j * node[cur].cnt) % mod;
node[next].cnt = (node[next].cnt + node[cur].cnt) % mod;
}
ans = (ans + node[cur].sum) % mod;
}
return ans;
}
private:
const static int SZ = 11;
struct State {
int len, link;
int next[SZ];
int sum, cnt;
};
State node[N << 1];
int sz, last;
};
SAM sam;
char s[123456]; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int n;
while (cin >> n) {
sam.init();
for (int i = 0; i < n; i ++) {
scanf("%s", s);
for (int j = 0; s[j]; j ++) {
sam.add(s[j] - '0');
}
sam.add(10);
}
cout << sam.getAns() << endl;
}
return 0;
}

  

[hdu4436 str2int]后缀自动机SAM(或后缀数组SA)的更多相关文章

  1. [转]后缀自动机(SAM)

    原文地址:http://blog.sina.com.cn/s/blog_8fcd775901019mi4.html 感觉自己看这个终于觉得能看懂了!也能感受到后缀自动机究竟是一种怎样进行的数据结构了. ...

  2. 后缀自动机(SAM)速成手册!

    正好写这个博客和我的某个别的需求重合了...我就来讲一讲SAM啦qwq 后缀自动机,也就是SAM,是一种极其有用的处理字符串的数据结构,可以用于处理几乎任何有关于子串的问题,但以学起来异常困难著称(在 ...

  3. 后缀自动机SAM学习笔记

    前言(2019.1.6) 已经是二周目了呢... 之前还是有一些东西没有理解到位 重新写一下吧 后缀自动机的一些基本概念 参考资料和例子 from hihocoder DZYO神仙翻译的神仙论文 简而 ...

  4. 后缀自动机SAM

    某神犇:"初三还不会后缀自动机,那就退役吧!" 听到这句话后,我的内心是崩溃的. 我还年轻,我还不想退役--于是,我在后来,努力地学习后缀自动机. 终于,赶在初三开学前,我终于学会 ...

  5. 后缀自动机(SAM)奶妈式教程

    后缀自动机(SAM) 为了方便,我们做出如下约定: "后缀自动机" (Suffix Automaton) 在后文中简称为 SAM . 记 \(|S|\) 为字符串 \(S\) 的长 ...

  6. 【算法】后缀自动机(SAM) 初探

    [自动机] 有限状态自动机的功能是识别字符串,自动机A能识别字符串S,就记为$A(S)$=true,否则$A(S)$=false. 自动机由$alpha$(字符集),$state$(状态集合),$in ...

  7. 【算法专题】后缀自动机SAM

    后缀自动机是用于识别子串的自动机. 学习推荐:陈立杰讲稿,本文记录重点部分和感性理解(论文语言比较严格). 刷题推荐:[后缀自动机初探],题目都来自BZOJ. [Right集合] 后缀自动机真正优于后 ...

  8. SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)

    1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...

  9. 浅谈后缀自动机SAM

    一下是蒟蒻的个人想法,并不很严谨,仅供参考,如有缺误,敬请提出 参考资料: 陈立杰原版课件 litble 某大神 某大神 其实课件讲得最详实了 有限状态自动机 我们要学后缀自动机,我们先来了解一下自动 ...

  10. 后缀自动机 (SAM)

    后缀自动机 定义 定义 SAM 为一个有限状态自动机,接受且仅接受 \(S\) 的一个后缀. 同时,SAM 是这样的自动机中最小的那个,其中状态数至多为 \(2n - 1\),转移数至多为 \(3n ...

随机推荐

  1. D-Power Products

    题目连接: 题解: 根据题目的意思,对每个X进行质因子分解,保存其质因子以及质因子出现的个数,如果两个数的乘积变成一个数的K次幂,那么两个数的质因子的指数之间相加应为k的倍数.保存完毕后,开始遍历,将 ...

  2. Java 网络编程 -- 基于TCP实现文件上传

    Java TCP 操作基本流程 一.创建服务器 1.指定端口, 使用serverSocket创建服务器 2.阻塞式连接 accept 3.操作:输入流 输出流 4.释放资源 二.创建客户端 1.使用S ...

  3. 用long类型让我出了次生产事故,写代码还是要小心点

    昨天发现线上试跑期的一个程序挂了,平时都跑的好好的,查了下日志是因为昨天运营跑了一家美妆top级淘品牌店,会员量近千万,一下子就把128G的内存给爆了,当时并行跑了二个任务,没辙先速写一段代码限流,后 ...

  4. Python Flask构建微信小程序订餐系统 学习 资源

    一.Flask MVC框架结构  1.1实际项目结构   1.2application.py  项目配置文件Flask之flask-script模块使用  static.py 文件(部署到生成环境不需 ...

  5. c++动态数组的使用

    在c++中,有的时候会遇到变长的数组(不管是一维的还是二维的),这个时候就需要用到动态数组了,并且要用new和delete两个操作符,这俩操作符一般成对使用. 先说一维的动态数组吧,直接上代码 #in ...

  6. 如何调试 Inno Setup

    从命令行运行安装包,并加上 /log=filename

  7. 怎么将swagger API导出为HTML或者PDF

    文章目录 将swagger API导出为HTML或者PDF 什么是Asciidoc swagger2markup-maven-plugin asciidoctor-maven-plugin 使用命令行 ...

  8. Leetcode PHP题解--D75 706. Design HashMap

    2019独角兽企业重金招聘Python工程师标准>>> D75 706. Design HashMap 题目链接 706. Design HashMap 题目分析 自行设计一个has ...

  9. Vue 2.x折腾记 - (17) 基于Ant Design Vue 封装一个配置式的表单组件

    前言 写了个类似上篇搜索的封装,但是要考虑的东西更多. 具体业务比展示的代码要复杂,篇幅太长就不引入了. 效果图 2019-04-25 添加了下拉多选的渲染,并搜索默认过滤文本而非值 简化了渲染的子组 ...

  10. swift 3.0字符串的简单使用

    let str:String = "12314124" 获取某个指定位置的元素 print(str.characters[str.index(str.startIndex, off ...