题意:给你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. 设置https以及http转https的问题

    公司用的是阿里云服务器win2008server r2 ,环境是phpwamp,出现许多问题.2018-11-12 一 设置https 1.设置httpd.ini 取消以下三个配置的# LoadMod ...

  2. openstack(Pike 版)集群部署(六)--- Horizon 部署

    一.介绍 参照官网部署:https://docs.openstack.org/horizon/pike/install/    继续上一博客进行部署:http://www.cnblogs.com/we ...

  3. Websocket实现群聊、单聊

    Websocket 使用的第三方模块:gevent-websocket 群聊 ws群聊.py中的内容 from flask import Flask, request, render_template ...

  4. PHP序列及反序列化安全漏洞

      尽量阐述全PHP序列化的相关东西-.- 1.序列化和反序列化   序列化是将变量或对象转换成字符串的过程:反序列化是将字符串转换成变量或对象的过程.   序列化及反序列化常见函数:serializ ...

  5. vue-webpack项目本地开发环境设置代理解决跨域问题

    前言: 一般跨域问题只要后端配置好的话,是不需要前端做处理的,但也不能保证你遇到的所有后端都能很好的处理这个问题,这个时候可能就需要前端设置代理解决这个问题了. 配置方法: 1. config/ind ...

  6. TCP/IP中的四元组、五元组、七元组

    四元组:源IP地址.目的IP地址.源端口.目的端口 五元组:源IP地址.目的IP地址.源端口.目的端口.传输层协议 七元组:源IP地址.目的IP地址.源端口.目的端口.传输层协议,服务类型以及接口索引

  7. Win7系统不能记忆窗口大小与位置解决方法

    似在某此系统优化后,无意发现系统在注销或重启后,打开资源管理器,它以默认大小及位置显示. 对于习惯自定义操作来说,甚为不便,遍找方法未有奏效者,但总萦绕心头,时时记起. 今日再找问题解决方法,难兄难弟 ...

  8. java命令启动jacocoagent及生成报告

    启动jacocoagent: java -Xms1024m -Xmx2048m -XX:-UseGCOverheadLimit -Ddruid.keepAlive=true -javaagent:/h ...

  9. oracle学习之数据库数据保存成文件

    常常需要将数据库中的数据生成文档,由于比较喜欢脚本的方式,所以就需要使用spool的时候进行格式设置,以下简单整理了一下oracle中进行格式设置的一些东西,一共十八条,其实常用的也就那么几个,稍后会 ...

  10. C# web服务器被webbench攻击及目现采用的防御措施

    web服务器连续两次出现CPU达到100%的情况,第一次还想着是升级时,哪个地方写错了,有死循环,最后重启了三次服务器才好. 但事后分析代码,没有死循环的可能,于是在第二次又出现CPU达100%时,仔 ...