[POI 2000] 公共串
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=2946
[算法]
建立多串后缀树
对于后缀树上的每个点 , 判断该节点所代表的等价类是否在所以字符串中出现 , 用该点的深度更新答案
时间复杂度 : O(NL)
[代码]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 1e5 + ;
const int ALPHA = ; int n , ans;
char s[N]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
} struct Suffix_Automaton
{
int sz , last;
int father[N] , child[N][ALPHA] , depth[N];
bool lab[N][];
vector< int > a[N];
Suffix_Automaton()
{
sz = ;
last = ;
}
inline int new_node(int dep)
{
depth[++sz] = dep;
father[sz] = ;
memset(child[sz] , , sizeof(child[sz]));
memset(lab[sz] , , sizeof(lab[sz]));
return sz;
}
inline void extend(int ch , int c)
{
int np = child[last][ch];
if (np)
{
if (depth[np] == depth[last] + )
{
lab[np][c] = true;
last = np;
} else
{
int nq = new_node(depth[last] + );
father[nq] = father[np];
father[np] = nq;
memcpy(child[nq] , child[np] , sizeof(child[nq]));
for (int p = last; child[p][ch] == np; p = father[p])
child[p][ch] = nq;
lab[nq][c] = true;
last = nq;
}
} else
{
int np = new_node(depth[last] + );
int p = last;
while (child[p][ch] == )
{
child[p][ch] = np;
p = father[p];
}
if (child[p][ch] == np)
{
father[np] = ;
lab[np][c] = true;
last = np;
return;
}
int q = child[p][ch];
if (depth[q] == depth[p] + )
{
father[np] = q;
lab[np][c] = true;
last = np;
return;
} else
{
int nq = new_node(depth[p] + );
father[nq] = father[q];
father[np] = father[q] = nq;
memcpy(child[nq] , child[q] , sizeof(child[q]));
while (child[p][ch] == q)
{
child[p][ch] = nq;
p = father[p];
}
lab[np][c] = true;
last = np;
return;
}
}
}
inline void insert(char *s , int col)
{
last = ;
for (int i = ; i <= strlen(s + ); ++i)
extend(s[i] - 'a' , col);
}
inline void dfs(int u)
{
for (unsigned i = ; i < a[u].size(); ++i)
{
int v = a[u][i];
dfs(v);
for (int j = ; j <= n; ++j)
lab[u][j] |= lab[v][j];
}
bool all = true;
for (int i = ; i <= n; ++i) all &= lab[u][i];
if (all) chkmax(ans , depth[u]);
}
inline void work()
{
for (int i = ; i <= sz; ++i)
a[father[i]].push_back(i);
dfs();
}
} SAM; int main()
{ read(n);
for (int i = ; i <= n; ++i)
{
scanf("%s" , s + );
SAM.insert(s , i);
}
SAM.work();
printf("%d\n" , ans); return ; }
[POI 2000] 公共串的更多相关文章
- BZOJ 2946: [Poi2000]公共串
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 787 Solved: 342[Submit][Status][D ...
- BZOJ 2946: [Poi2000]公共串( 后缀自动机 )
一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...
- 【BZOJ2946】公共串(后缀数组)
[BZOJ2946]公共串(后缀数组) 题面 权限题... 只有CJOJ题面啦 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: 读入单词,计算最长公共子串的 ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- 【BZOJ】【2946】【POI2000】公共串
后缀数组 好感动,复习了下后缀数组居然写出来了……(感谢ykz大神) 求最长公共子串……WA了一发是因为:[不同字符串之间要用不同的特殊字符隔开]否则就会匹配到相同→_→比如都是aaa结尾,如果用相同 ...
- 【BZOJ2946】[Poi2000]公共串 后缀数组+二分
[BZOJ2946][Poi2000]公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计 ...
- 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)
2946: [Poi2000]公共串 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 1063 Solved: 469 Description ...
- 【BZOJ2946】公共串 [SAM]
公共串 Time Limit: 3 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给出几个由小写字母构成的单词,求它们最 ...
- [BZOJ2946] [Poi2000]公共串解题报告|后缀数组
给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000 尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...
随机推荐
- Java多线程下载文件
package com.test.download; import java.io.File; import java.io.InputStream; import java.io.RandomA ...
- HTML5 2D平台游戏开发#3冲刺
断断续续地把Demo又写了一阵,终于把角色的冲刺动作完成了.冲刺的作用是使角色能够快速移动,闪避攻击或障碍.其完成效果如下: 首先,仍需要一些变量来表示角色的冲刺状态: //标识角色是否处于冲刺中 v ...
- Option可选值可选值(二)
//: Playground - noun: a place where people can play import Cocoa var str1 = "供选链接和强制拆包的不同. &qu ...
- MongoDB查询语句(转)
目录 查询操作 集合查询方法 find() 查询内嵌文档 查询操作符(内含 数组查询) "$gt" ."$gte". "$lt". &quo ...
- Grunt学习笔记【4】---- 通配符和模板
本文主要讲通配符和模板的基本使用方法. 一 通配符 通常分别指定所有源文件路径是不切实际的,因此Grunt通过内置支持node-glob 和 minimatch 库来匹配文件名(又叫作globbing ...
- 一起来学linux:ACL
传统的 权限设置只有user,group,other三种,并没有办法针对某一个用户或者某一个组来设定权限.ACL就是用于这个目的的 那 ACL 主要可以针对哪些方面来控制权限呢?他主要可以针对几个项目 ...
- tensorflow:typeerror:‘noneType’ object is not callable
程序运行报错 typeerror: ‘noneType’ object is not callable 解决方法:删除缓存文件,再次运行没有错误 删除__pycache__文件夹
- Carthage的使用
1.安装Carthage https://github.com/Carthage/Carthage/releases 2.进入Cartfile文件所在的目录地址 cd 拖入文件Cartfile,把最后 ...
- c#应用程序带参数运行
有时候我们需要让软件带参数运行,使用参数控制软件的部分行为, C#默认窗口应用是不带参数的,不过在Main函数的参数手动加上就可以得到参数了. 举例如下: /// <summary> // ...
- Java中的内存泄漏
[转]介绍Java中的内存泄漏 1. 什么是内存泄漏? 内存泄漏的定义:对象已经没有被应用程序使用,但是垃圾回收器没办法移除它们,因为还在被引用着. 要想理解这个定义,我们需要先了解一下对象在内存中的 ...