hdu 6208(后缀自动机、或者AC自动机
题意:给你n个字符串,问你是否存在一个字符串可以从中找到其他n-1个字符串。
思路:其实很简单,找到最长的那个字符串对他进行匹配,看是否能匹配到n-1个字符串。
可以用AC自动机或者后缀自动机做,但是AC自动机用指针的话会MLE,但是我比赛的时候用自己的后缀自动机的板子T了!
然后用了dalao的板子,还是我的板子不够优秀啊(┬_┬)
AC自动机版:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=1e5+;
const int maxm=*;
const int SIGMA_SIZE=;
int n;
char t[maxn],s[maxn]; struct AC
{
int ch[maxm][];
int val[maxm];
int fail[maxm],last[maxm];
int sz;
void clear(){memset(ch[],,sizeof(ch[]));sz=;}
int idx(char x){return x-'a';}
void insert(char *s)
{
int u=;
int n=strlen(s);
for(int i=;i<n;i++)
{
int c=idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]++;
}
void getfail()
{
queue<int> q;
fail[]=;
int u=;
for(int i=;i<SIGMA_SIZE;i++)
{
u=ch[][i];
if(u){q.push(u);fail[u]=;last[u]=;}
}
while(!q.empty())
{
int r=q.front();q.pop();
for(int i=;i<SIGMA_SIZE;i++)
{
u=ch[r][i];
if(!u){ch[r][i]=ch[fail[r]][i];continue;}
q.push(u);
int v=fail[r];
while(v&&!ch[v][i])v=fail[v];
fail[u]=ch[v][i];
last[u]=val[fail[u]]?fail[u]:last[fail[u]];
}
}
}
int find(char *s)
{
int u=,cnt=;
int n=strlen(s);
for(int i=;i<n;i++)
{
int c=idx(s[i]);
u=ch[u][c];
int temp=;//必须赋初值为0,表示如果下面两个判断都不成立的时候while可以正常执行
if(val[u])
temp=u;
else if(last[u])
temp=last[u];
while(temp)
{
cnt+=val[temp];
val[temp]=;
temp=last[temp];
}
}
return cnt;
}
}tree;
string a[maxn];
void solve()
{
scanf("%d",&n);
tree.clear();
int maxx=, id=;
for(int i=;i<=n;i++)
{
scanf("%s",t);
tree.insert(t);
int len=strlen(t);
if (len>maxx) {
maxx=len;
id=i;
}
a[i]=string(t);
}
tree.getfail();
int len=a[id].length();
for (int i=; i<len; i++)
t[i]=a[id][i];
int ans=tree.find(t);
//printf("%d\n",ans);
if (ans==n) puts(t);
else puts("No"); }
int main() {
int t = ;
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d", &t);
while(t--)
solve();
return ;
}
后缀自动机:
/** @xigua */
#include <stdio.h>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstring>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <climits>
#define PI acos(-1)
#define rep(a,b,c) for(int (a)=(b); (a)<(c); ++(a))
#define drep(a,b,c) for(int (a)=(b); (a)>(c); --(a))
#define CLR(x) memset(x, 0, sizeof(x))
#define sf scanf
#define pf printf
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e5 + ;
const int ma = 1e5 + ;
const int mod = 1e9 + ;
const int INF = 1e8 + ;
const ll inf = 1e17 + ;
const db eps = 1e-;
const int MAXN = 2e5+1e3;
char pool[MAXN]; struct Str{
int st, len;
}str[MAXN];
struct state {
int len, pre, ch[];
};
struct SAM {
int sz, last;
state st[MAXN];
state& operator[] (int x) {
return st[x];
}
void clear(int x) {
CLR(st[x].ch);
}
void init() {
sz=, last=;
st[].len=, st[].pre=-;
clear();
}
void add(int c) {
int cur=sz++, p;
clear(cur);
st[cur].len=st[last].len+;
for(p=last; p!=-&&!st[p].ch[c]; p=st[p].pre)
st[p].ch[c]=cur;
if(p==-) st[cur].pre=;
else {
int q=st[p].ch[c];
if(st[q].len==st[p].len+)
st[cur].pre=q;
else {
int clone=sz++;
st[clone]=st[q];
st[clone].len=st[p].len+;
st[cur].pre=st[q].pre=clone;
for(; p!=-&&st[p].ch[c]==q; p=st[p].pre)
st[p].ch[c]=clone;
}
}
last=cur;
}
int find(string t) {//查询lcs
int now=, l=, ans=;
int len=t.length();
for (int i=; i<len; i++) {
while(now&&!st[now].ch[t[i]-'a']) {
now=st[now].pre;
l=st[now].len;
}
if(st[now].ch[t[i]-'a']) {
++l;
now=st[now].ch[t[i]-'a'];
}
ans=max(l, ans);
}
return ans;
}
} sam;
string a[maxn];
bool check(int sel, int n) {
for (int i=; i<n; i++) {
if (i!=sel) {
if (sam.find(a[i])!=a[i].length()) return ;
}
}
return true;
}
char ans[maxn];
void solve() {
int n; scanf("%d", &n);
str[].st=;
int sel=, maxx=;
for (int i=; i<n; i++) {
scanf("%s", pool);
int len=strlen(pool);
if (len>maxx) {
maxx=len;
sel=i;
}
a[i]=string(pool);
}
sam.init();
int len=a[sel].length();
for (int i=; i<len; i++)
sam.add(a[sel][i]-'a');
for (int i=; i<len; i++)
ans[i]=a[sel][i];
if(check(sel,n)) {
int l=a[sel].length();
for (int i=; i<len; i++)
printf("%c", ans[i]);
puts("");
}
else puts("No");
}
int main() {
int t = , cas = ;
//freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
scanf("%d", &t);
while(t--) {
// printf("Case %d: ", cas++);
solve();
}
return ;
}
hdu 6208(后缀自动机、或者AC自动机的更多相关文章
- hdu 4117 GRE Words (ac自动机 线段树 dp)
参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...
- HDU 3341 Lost's revenge AC自动机+dp
Lost's revenge Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- HDU 2457 DNA repair(AC自动机+DP)题解
题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...
- HDU 2222 Keywords Search(AC自动机)题解
题意:给你几个keywords,再给你一段文章,问你keywords出现了几次. 思路:这里就要用到多模匹配算法AC自动机了,AC自动机需要KMP和字典树的知识,匹配时是在字典树上,失配我们就要用到类 ...
- HDU - 6096 :String (AC自动机,已知前后缀,匹配单词,弱数据)
Bob has a dictionary with N words in it. Now there is a list of words in which the middle part of th ...
- HDU 2222 Keywords Search 【AC自动机】
题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=2222] 题意:给出很多小字符串,然后给出一个文本串,问文本串中包含多少个小字符串.也就是说如果文本串 ...
- HDU 5384 字典树、AC自动机
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 #include<stdio.h> #includ ...
- HDU 2896 病毒侵袭(AC自动机)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 2222 Keywords Search (AC自动机)
题意:给你一些模式串,再给你一串匹配串,问你在匹配串中出现了多少种模式串,模式串可以相同 AC自动机:trie树上进行KMP.首先模式串建立trie树,再求得失配指针(类似next数组),其作用就是在 ...
随机推荐
- 排列组合或容斥原理 SPOJ - AMR11H
题目链接: https://vjudge.net/contest/237052#problem/H 这里给你一串数字,让你计算同时拥有这串数字最大值和最小值的子集(连续)和子序列(可以不连续)的数量, ...
- 安装python3 及virtual与virtualenvwrapper
安装python3 下载python源码包 网址:https://www.python.org/downloads/release/python-362/ 下载地址:https://www.pytho ...
- cisco 3850 GBIC报错处理
今天有用户cisco 3850插入多模千兆光模块后报错日志如下: *Oct 18 13:48:54: %PLATFORM_PM-6-MODULE_ERRDISABLE:The inserted SFP ...
- stm32架构初认识
刚接触stm32f373c8t6的芯片,这到底是怎末开发的,应该说它是SOC,内部有一个核心芯片,然后在芯片的外部添加了一些有特殊功能的外设,使开发者能够完成想要的功能,以stm32f373c 8t6 ...
- 微信小程序开发——开发者工具中素材管理功能使用的注意事项
为什么使用“素材管理”: 微信小程序环境中本地资源图片是无法通过 WXSS 获取的,可以使用网络图片,或者 base64,或者使用<image/>标签.. 当然,如果不想这么麻烦,你可能会 ...
- ngular ionic select ng-options 默认选择第一个值的写法
1. html <select ng-model="selectOrderState" style="border:none;left:0" ng-opt ...
- 超强、超详细Redis入门教程【转】
这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用red ...
- php libev扩展使用
在WorkerMan源码分析 - 实现最简单的原型文章中提到了libevent网络库,前者和libev都是事件驱动编程库高性能.简单说libev对libevent做了改进和精简.libevent使用全 ...
- echarts柱形图x轴显示不全或者每隔一个不显示的问题
问题原因可能:x轴数据间隔太小: 问题解决: 1.调整间隔属性 xAxis: { type: 'category', //坐标轴斜着显示 axisLabel: { interval:0, rotate ...
- Struts2框架之Action类的访问
1. 通过<action>标签中的method属性,访问到Action中的具体的方法. * 传统的配置方式,配置更清晰更好理解!但是扩展需要修改配置文件等! * 具体的实例如下: * 页面 ...