题意:给出串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;
}

  

最新文章

  1. Entity Framework 6 Recipes 2nd Edition(13-4)译 -&gt; 有效地创建一个搜索查询
  2. @UniqueConstraint
  3. mysql 源码安装
  4. 转: MVC设计思想简介
  5. 【C++基础】 各种“虚”总结(ing...)
  6. DB2建表语句
  7. 【高性能】生成唯一时间戳ID,1毫秒预计能生成1000个
  8. A tuple is defined as a function
  9. vue 通知 走马灯效果
  10. 我发起了一个 支持 ServerFul 架构 的 .Net 开源项目 ServerFulManager
  11. 20175314 实验二 Java面向对象程序设计
  12. (三)JavaScript 语法
  13. 微信小程序场景值
  14. 字符串匹配的KMP算法-16张图片看明白
  15. laravel5.3之后可以使用withCount()这个方法
  16. bzoj 3672 购票 点分治+dp
  17. VS2012与VS2015同时安装用VS2012创建MFC程序时弹出编译错误”fatal error C1083: 无法打开包括文件:“mprapidef.h”: No such file or directory”的解决办法
  18. mysql json
  19. Crash for small compressed texture on some Android device
  20. 压缩JS,提高代码执行速度

热门文章

  1. mongo基础
  2. vue如何添加jquery?
  3. 百度paddlepaddle学习体会
  4. Spring Cloud 系列之 Sleuth 链路追踪(三)
  5. 十六, Oracle约束
  6. BareTail 观看文件增加的工具
  7. Iterator to list的三种方法
  8. linux 之学习路线
  9. 面向对象(OO)第二阶段学习总结
  10. c语言----实战植物大战僵尸