题意:给出串A和串集合B={B1,B2,...,Bn},求串A的所有不同子串中不是B中任一串的子串的数目。

思路:把A和B中所有字符串依次拼接在一起,然后构造后缀自动机,计算每个状态的R集合元素的最大值r,然后统计那些r≤length(A)的状态。hdu不卡时间卡空间,这是最郁闷的。。。导致下面的程序只在本地随机数据没发现错误,提交就MLE。

#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 N = 6e5 + 7; int len; //注意空间为 DOUBLE SIZE
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;
node[cur].r = node[cur].len;
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].link = node[q].link;
memcpy(node[clone].next, node[q].next, sizeof(node[q].next));
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], p[N];
ll 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;
for (int i = sz - 1; i >= 0; i --) {
int cur = p[i];
if (cur == 0) continue;
umax(node[node[cur].link].r, node[cur].r);
}
ll ans = 0;
for (int i = 1; i < sz; i ++) {
if (node[i].r <= len) ans += node[i].len - node[node[i].link].len;
}
return ans;
}
private:
const static int SZ = 27;
struct State {
int len, link;
int r;
int next[SZ];
};
State node[N];
int sz, last;
};
SAM sam;
char s[N]; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int n;
cas() {
cin >> n;
sam.init();
for (int i = -1; i < n; i ++) {
scanf("%s", s);
if (i < 0) len = strlen(s);
for (int j = 0; s[j]; j ++) {
sam.add(s[j] - 'a');
}
sam.add(26);
}
printf("Case %d: %I64d\n", ++ cas, sam.getAns());
}
return 0;
}

  

[hdu4416 Good Article Good sentence]后缀自动机SAM的更多相关文章

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

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

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

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

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

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

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

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

  5. 浅谈后缀自动机SAM

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

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

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

  7. 后缀自动机SAM BZOJ 2806

    终于遇到了一道后缀数组不能过 一定要学SAM的题... (看了半个下午+半个上午) 现在总结一下(是给我自己总结..所以只总结了我觉得重要的 .. 看不太懂的话可以To   http://blog.c ...

  8. 【算法】后缀自动机(SAM) 例题

    算法介绍见:http://www.cnblogs.com/Sakits/p/8232402.html 广义SAM资料:https://www.cnblogs.com/phile/p/4511571.h ...

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

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

随机推荐

  1. D - Catch That Cow BFS

    农夫知道一头牛的位置,想要抓住它.农夫和牛都于数轴上 ,农夫起始位于点 N(0<=N<=100000) ,牛位于点 K(0<=K<=100000) .农夫有两种移动方式: 1. ...

  2. google protobuf c++ 反射

    const Descriptor *desc = DescriptorPool::generated_pool()->FindMessageTypeByName(msg_name); asser ...

  3. 01、WireShark——ARP 协议包分析

     1. 什么是ARP ARP(Address Resolution Protocol)协议,即地址解析协议.该协议的功能就是将 IP 地 址解析成 MAC 地址. ARP(Address Resolu ...

  4. mac上搭建mysql环境配置和Navicat连接mysql

    mac上搭建mysql环境配置 1.下载mysql for mac: https://downloads.mysql.com/archives/community/ 注意:mysql版本要和你的MAC ...

  5. bugku ctf 逆向题

    1.逆向入门 2.Easy_vb 直接找出来. 3.easy_re 4.游戏过关 摁着嗯着就出来了... 5.Timer{阿里ctf} apk文件,不会搞. 6.逆向入门 发现是base64,直接转图 ...

  6. 常见分布式全局唯一ID生成策略

    全局唯一的 ID 几乎是所有系统都会遇到的刚需.这个 id 在搜索, 存储数据, 加快检索速度 等等很多方面都有着重要的意义.工业上有多种策略来获取这个全局唯一的id,针对常见的几种场景,我在这里进行 ...

  7. Pytorch实现的语义分割器

    使用Detectron预训练权重输出 *e2e_mask_rcnn-R-101-FPN_2x* 的示例 从Detectron输出的相关示例 使用Detectron预训练权重输出 *e2e_keypoi ...

  8. Elasticsearch系列---实现分布式锁

    概要 Elasticsearch在文档更新时默认使用的是乐观锁方案,而Elasticsearch利用文档的一些create限制条件,也能达到悲观锁的效果,我们一起来看一看. 乐观锁与悲观锁 乐观锁 E ...

  9. [USACO3.2]魔板 Magic Squares

    松下问童子,言师采药去. 只在此山中,云深不知处.--贾岛 题目:魔板 Magic Squares 网址:https://www.luogu.com.cn/problem/P2730 这是一张有8个大 ...

  10. java中ThreadPool的介绍和使用

    文章目录 Thread Pool简介 Executors, Executor 和 ExecutorService ThreadPoolExecutor ScheduledThreadPoolExecu ...