POJ 3518 Boring

Problem : 给一个串S,询问串S有多个子串出现至少两次且位置不重叠。

Solution : 对S串建立后缀自动机,再建立后缀树,dfs一遍统计处每个结点的子树中最长节点max和最短节点min。枚举一遍后缀自动机的节点,那么对于其对应后缀的长度要求为小于等于max - min。

#include <iostream>
#include <algorithm> using namespace std; const int N = 1000008;
const int INF = 2000000008; struct edge
{
int u, v, nt;
}; struct suffix_automanon
{
int nt[N][26], fail[N], a[N], qmin[N], qmax[N];
int tot, last, root;
int lt[N], sum;
int p, q, np, nq;
edge eg[N << 1];
void add(int u, int v)
{
eg[++sum] = (edge){u, v, lt[u]}; lt[u] = sum;
}
int newnode(int len)
{
for (int i = 0; i < 26; ++i) nt[tot][i] = -1;
fail[tot] = -1; a[tot] = len; qmax[tot] = 0; qmin[tot] = INF;
lt[tot] = 0;
return tot++;
}
void clear()
{
tot = 0;
root = last = newnode(0);
}
void insert(int ch)
{
p = last; np = last = newnode(a[p] + 1); qmin[np] = qmax[np] = a[np];
for (; ~p && nt[p][ch] == -1; p = fail[p]) nt[p][ch] = np;
if (p == -1) fail[np] = root;
else
{
q = nt[p][ch];
if (a[p] + 1 == a[q]) fail[np] = q;
else
{
nq = newnode(a[p] + 1);
for (int i = 0; i < 26; ++i) nt[nq][i] = nt[q][i];
fail[nq] = fail[q];
fail[q] = fail[np] = nq;
for (; ~p && nt[p][ch] == q; p = fail[p]) nt[p][ch] = nq;
}
}
}
void dfs(int u)
{
for (int i = lt[u]; i; i = eg[i].nt)
{
// cout << u << " " << eg[i].v << endl;
int v = eg[i].v;
dfs(v);
qmax[u] = max(qmax[u], qmax[v]);
qmin[u] = min(qmin[u], qmin[v]);
}
}
void solve()
{
long long ans = 0;
for (int i = 1; i < tot; ++i) add(fail[i], i);
dfs(root);
// for (int i = 1; i < tot; ++i) cout << qmin[i] << " " << qmax[i] << endl;
for (int i = 1; i < tot; ++i)
{
int len = qmax[i] - qmin[i];
if (len > a[fail[i]]) ans += min(a[i], len) - a[fail[i]];
}
cout << ans << endl;
} }sam; int main()
{
string s;
while (cin >> s)
{
if (s == "#") break;
sam.clear();
for (int i = 0, len = s.length(); i < len; ++i)
sam.insert(s[i] - 'a');
sam.solve();
}
}

最新文章

  1. C++小项目:directx11图形程序(八):particleSysclass
  2. 使用git提交中删除idea
  3. 使用 gulp 搭建前端环境入门篇(转载)
  4. 游戏服务器端引擎--DogSE的设计
  5. 关于MonoDevelop自动缩进的设置
  6. MySQL中EXPLAIN解释命令详解
  7. OpenStack Networking
  8. Python 学习日记(第四周)
  9. 设置Eclipse启动JDK
  10. [Swust OJ 643]--行列式的计算(上三角行列式变换)
  11. 【Python学习笔记之一】Python关键字及其总结
  12. JS正则表达式的基础用法
  13. 移动端遇到的问题小结--video
  14. 51nod 1277 字符串中的最大值
  15. MAC使用mysql报错:ERROR 1045 (28000): Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password: YES)
  16. 机器学习、深度学习以及人工智能正在快速演进(ML、DL、AI)
  17. win7.wifi热点
  18. Spring学习(四)—— java动态代理(JDK和cglib)
  19. python - web自动化测试 - 元素操作 - 鼠标键盘
  20. CodeForces 659E New Reform

热门文章

  1. [转]MySQL游标的使用
  2. 移动端UI自动化Appium测试——Windows系统Appium环境配置
  3. php微信自动发红包
  4. AJPFX关于Java Object类常用方法小总结
  5. Java操作pdf: JarsperReport的简单使用
  6. GCC的函数声明问题
  7. swift class type isa-swizzling
  8. js 脚本语言
  9. bind - 将一个名字和一个套接字绑定到一起
  10. Vue beaforeCreate时获取data中的数据