题意:给你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自动机的更多相关文章

  1. hdu 4117 GRE Words (ac自动机 线段树 dp)

    参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...

  2. 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 ...

  3. HDU 2457 DNA repair(AC自动机+DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

  4. HDU 2222 Keywords Search(AC自动机)题解

    题意:给你几个keywords,再给你一段文章,问你keywords出现了几次. 思路:这里就要用到多模匹配算法AC自动机了,AC自动机需要KMP和字典树的知识,匹配时是在字典树上,失配我们就要用到类 ...

  5. 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 ...

  6. HDU 2222 Keywords Search 【AC自动机】

    题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=2222] 题意:给出很多小字符串,然后给出一个文本串,问文本串中包含多少个小字符串.也就是说如果文本串 ...

  7. HDU 5384 字典树、AC自动机

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 #include<stdio.h> #includ ...

  8. HDU 2896 病毒侵袭(AC自动机)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDU 2222 Keywords Search (AC自动机)

    题意:给你一些模式串,再给你一串匹配串,问你在匹配串中出现了多少种模式串,模式串可以相同 AC自动机:trie树上进行KMP.首先模式串建立trie树,再求得失配指针(类似next数组),其作用就是在 ...

随机推荐

  1. Vue.Draggable:基于 Sortable.js 的 Vue 拖拽组件使用中遇到的问题

    Sortable.js 介绍 https://segmentfault.com/a/1190000008209715 项目中遇到的问题: A - 我需要在项目的拖拽组件中,使用背景 1 - 想到的第一 ...

  2. .linearDrag on rigidbody / rigidbody2D in code?

    it's rigidbody.drag not .linearDrag 这几天在做一个弹球的游戏,发现小球落下后不会自动停,测试后发现线性阻尼增加后可以 于是加了个触发器不停增加线性阻尼值 priva ...

  3. maven 打 fat包(jar包有了全部依赖)插件

    <plugin> <artifactId> maven-assembly-plugin </artifactId> <configuration> &l ...

  4. TZOJ 数据结构期末历年题目

    A.数据结构练习题――线性表操作 线性表的基本操作 1.在某个位置p插入val,复杂度O(p) 2.在某个位置p删除val,复杂度O(p) 3.查找某个位置p的值,复杂度O(p) 4.清除链表,复杂度 ...

  5. IntelliJ IDEA 运行 Maven 项目

    1.官方文档说IntelliJ IDEA已经自身集成了maven,则不用劳心去下载maven 2.导入一个程序,看是否是maven程序的关键在于工程之中有没有pom.xml这个文件,比如这里   3. ...

  6. [leetcode]528. Random Pick with Weight按权重挑选索引

    Given an array w of positive integers, where w[i] describes the weight of index i, write a function  ...

  7. 使用BootStrap框架中的轮播插件

    在使用bootstrap框架中的轮播插件时,效果做出来后,无法通过点击小圆行的按钮来选择特定的图片. 后面发现是最开始的<div>标签中少写了一个id.一开始<div>标签是这 ...

  8. Web API、WCF和Web Service的区别

    [转载] Web Service 1.它是基于SOAP协议的,数据格式是XML 2.只支持HTTP协议 3.它不是开源的,但可以被任意一个了解XML的人使用 4.它只能部署在IIS上 WCF 1.这个 ...

  9. JAVA动手动脑及课后作业

    1.查看其输出结果.如何解释这样的输出结果?从中你能总结出什么? 运行结果 true true false 原因 1)在Java中,内容相同的字串常量(“Hello”)只保存一份以节约内存,所以s0, ...

  10. (转)OOP(面向对象编程)的几大原则

    文章转载自:http://blog.csdn.net/anders_zhuo/article/details/8949566 设计模式遵循的一般原则: 1.开-闭原则(Open-Closed Prin ...