太可惜了:基本什么方法都能过..我们老是想着sam..
简略题意:问是否存在一个串,其他串都是他的子串
ac自动机: (输入挂很重要..)
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i = a; i <= b; ++i)
#define FOR(i,a,b) for(int i = a; i < b; ++i)
#define mem(a,b) memset(a,b,sizeof(a))
#define MP make_pair
typedef long long LL;
typedef pair<int,int> pii;
namespace FastIO {
#define BUF_SIZE 100010 //缓冲区大小可修改
bool IOError = 0; //IOError == false 时表示处理到文件结尾
inline char NextChar() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOError = 1;
return -1;
}
}
return *p1++;
}
inline bool Blank(char c) {
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
}
inline void read(int &x){
bool sign=0; char ch=NextChar(); x=0;
for (;Blank(ch);ch=NextChar());
if (IOError)return;
if (ch=='-')sign=1,ch=NextChar();
for (;ch>='0'&&ch<='9';ch=NextChar())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(long long &x){
bool sign=0; char ch=NextChar(); x=0;
for (;Blank(ch);ch=NextChar());
if (IOError)return;
if (ch=='-')sign=1,ch=NextChar();
for (;ch>='0'&&ch<='9';ch=NextChar())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(double &x){
bool sign=0; char ch = NextChar(); x=0;
for (;Blank(ch);ch = NextChar());
if (IOError)return;
if (ch=='-')sign=1,ch=NextChar();
for (;ch>='0'&&ch<='9';ch=NextChar())x=x*10+ch-'0';
if (ch=='.'){
double tmp=1; ch=NextChar();
for (;ch>='0'&&ch<='9';ch=NextChar())tmp/=10.0,x+=tmp*(ch-'0');
}
if (sign)x=-x;
}
inline void read(char *s){
char ch=NextChar();
for (;Blank(ch);ch=NextChar());
if (IOError)return;
for (;!Blank(ch)&&!IOError;ch=NextChar())*s++=ch;
*s=0;
}
inline void read(char &c){
for (c=NextChar();Blank(c);c=NextChar());
if (IOError){c=-1;return;}
}
}
using namespace FastIO;
const int maxn = 100000;
const int maxnode = 100000, c_sz = 26;
bool vist[maxn + 5];
struct Tire {
int top;
int nex[maxnode + 5][c_sz], val[maxnode + 5];
int go[maxnode + 5], go_len[maxnode + 5];
int fail[maxnode + 5], last[maxnode + 5];
void clear() {
top = val[0] = 0;
mem(nex[0], 0);
}
inline int c_id(char c) { return c - 'a'; }
bool Insert(char *a, int len, int vv) {
int u = 0, t;
for(int i = 0; i < len; ++i) {
t = c_id(a[i]);
if(!nex[u][t]) {
nex[u][t] = (++top), val[top] = 0;
mem(nex[top], 0);
}
u = nex[u][t];
}
if(val[u])
vist[vv] = 1;
else
val[u] = vv;
}
void GetFail() {
fail[0] = last[0] = 0;
queue<int> q;
for(int i = 0; i < c_sz; ++i) if(int &t = nex[0][i]) {
fail[t] = last[t] = 0;
q.push(t);
}
while(!q.empty()) {
int x = q.front(); q.pop();
for(int i = 0; i < c_sz; ++i) {
int u = nex[x][i];
if(!u) { nex[x][i] = nex[fail[x]][i]; continue; }
q.push(u);
int v = fail[x];
while(v && !nex[v][i]) v = fail[v];
fail[u] = nex[v][i];
last[u] = val[fail[u]] ? fail[u] : last[fail[u]];
}
}
}
void find(int x) {
if(x) {
vist[val[x]] = 1;
find(last[x]);
}
}
void Run(char *a, int len) {
int u = 0;
for(int i = 0; i < len; ++i) {
int t = c_id(a[i]);
u = nex[u][t];
vist[val[u]] = 1;
find(last[u]);
}
}
} AC;
int llen[maxn + 5], pos[maxn + 5];
char str[maxn + 5];
int main() {
int xx, ll, n, T;
//scanf("%d", &T);
read(T);
while(T--) {
//scanf("%d", &n);
read(n);
pos[0] = 0, llen[0] = 0;
xx = 0, ll = 0;
AC.clear();
for(int i = 1; i <= n; ++i) {
vist[i] = 0;
pos[i] = pos[i - 1] + llen[i - 1];
//scanf("%s", str + pos[i]);
read(str + pos[i]);
llen[i] = strlen(str + pos[i]);
AC.Insert(str + pos[i], llen[i], i);
if(ll < llen[i])
xx = i, ll = llen[i];
}
AC.GetFail();
AC.Run(str + pos[xx], ll);
int fg = 1;
for(int i = 1; i <= n; ++i) {
if(!vist[i]) {
fg = 0;
break;
}
}
if(fg) {
for(int i = 0; i < ll; ++i)
printf("%c", *(str + pos[xx] + i));
printf("\n");
}
else printf("No\n");
}
return 0;
}
ac自动机(2):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <string>
#include <cstring>
#include <ctime>
#include <queue>
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N = 100010;
const int M = 26;
struct AC
{
int ch[N][M], fail[N], val[N];
int sz;
void init()
{
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
memset(val, 0, sizeof(val));
}
int idx(char c)
{
return c - 'a';
}
void add(char *s)
{
int n, now = 0;
n = strlen(s);
for (int i = 0; i < n; i++)
{
int id = idx(s[i]);
if (ch[now][id] == 0)
{
memset(ch[sz], 0, sizeof(ch[sz]));
ch[now][id] = sz++;
}
now = ch[now][id];
}
val[now]++;
}
void Build()
{
queue<int>que;
fail[0] = 0;
for (int i = 0; i < M; i++)
{
int u = ch[0][i];
if (u)
{
fail[u] = 0;
que.push(u);
}
}
while (!que.empty())
{
int r = que.front();
que.pop();
for (int c = 0; c < M; c++)
{
int u = ch[r][c];
if (!u)
{
continue;
}
que.push(u);
int v = fail[r];
while (v && !ch[v][c])
{
v = fail[v];
}
fail[u] = ch[v][c];
}
}
}
int Query(char *s)
{
int n, now = 0, ans = 0;
n = strlen(s);
for (int i = 0; i < n; i++)
{
int id = idx(s[i]);
while (now && !ch[now][id])
{
now = fail[now];
}
now = ch[now][id];
int t = now;
while (t && val[t] != -1)
{
ans += val[t];
val[t] = -1;
t = fail[t];
}
}
return ans;
}
} ac;
char s[100010], a[100010];
int main()
{
ios::sync_with_stdio(false);
int T, n;
cin >> T;
while (T--)
{
cin >> n;
if (n == 0)
{
cout << "No" << endl;
continue;
}
int maxx = 0, hh = n, len;
ac.init();
while (hh--)
{
cin >> a;
len = strlen(a);
ac.add(a);
if (len > maxx)
{
maxx = len;
strcpy(s, a);
s[len] = '\0';
}
}
ac.Build();
if (ac.Query(s) == n)
{
cout << s << endl;
}
else
{
cout << "No" << endl;
}
}
return 0;
}
sam:
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int MAXN = 110005;
struct SAM_Node{
int mxn;int ch[26];
int par;int right;
void init(){
mxn = 0,par = -1,right = -1;
memset(ch, -1, sizeof(ch));
}
} sampool[170005];
int samtot;
inline int samlen(int x){
if(sampool[x].par != -1) return sampool[x].mxn - sampool[sampool[x].par].mxn;
return sampool[x].mxn;
}
inline int samalloc(){
sampool[samtot].init();
return samtot++;
}
inline void samclone(int src,int dst){
sampool[dst] = sampool[src];
}
inline void saminit(){
samtot = 0;
sampool[samtot++].init();
}
int samappend(int lst,int x){
x -= 'a';
int p = lst;
int np = samalloc();
sampool[np].mxn = sampool[p].mxn + 1;
while(p != -1 && sampool[p].ch[x] == -1){
sampool[p].ch[x] = np;
p = sampool[p].par;
}
if(p != -1){
int q = sampool[p].ch[x];
if(sampool[q].mxn == sampool[p].mxn + 1){
sampool[np].par = q;
}else{
int nq = samalloc();
samclone(q,nq);
sampool[nq].right = -1;
sampool[nq].mxn = sampool[p].mxn + 1;
sampool[q].par = sampool[np].par = nq;
while(q != -1 && sampool[p].ch[x] == q){
sampool[p].ch[x] = nq;
p = sampool[p].par;
}
}
}else{
sampool[np].par = 0;
}
return np;
}
int N;
char buf[MAXN];
struct String{
int l;int r;
int len(){
return r-l+1;
}
bool operator < (const String &b) const{
return (r-l+1) < (b.r-b.l+1);
}
} str[MAXN];
int tot = 0;
int main(){
int caseCnt = 0;
scanf(" %d",&caseCnt);
for(int __ = 1; __ <= caseCnt; ++__){
scanf(" %d",&N);
tot = 0;
for(int i = 1;i <= N; i++){
scanf(" %s",buf+tot);
str[i].l = tot;
tot += strlen(buf+tot);
str[i].r = tot-1;
}
sort(str+1,str+1+N);
saminit();
int lst = 0;
for(int i = str[N].l; i <= str[N].r; i++){
lst = samappend(lst,buf[i]);
}
bool pass = true;
for(int i = 1;i < N; i++){
int cur = 0;
for(int j = str[i].l; j <= str[i].r; j++){
if(sampool[cur].ch[buf[j]-'a'] == -1){
pass = false;
break;
}
cur = sampool[cur].ch[buf[j]-'a'];
}
if(!pass) break;
}
if(pass){
for(int i = str[N].l; i <= str[N].r; i++){
putchar(buf[i]);
}
puts("");
}else{
puts("No");
}
}
return 0;
}
kmp
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define MP make_pair
#define ULL unsigned long long
#define LL long long
#define inf 0x3f3f3f3f
#define md ((ll+rr)>>1)
#define ls (i<<1)
#define rs (ls|1)
#define eps 1e-5
#define ree freopen("in.txt","r",stdin);
#define bug pf("----------------");
#define N 100010
#define M 1000020
int n;
int f[N];
void getfail(char *p){
f[0]=f[1]=0;
int len=strlen(p);
for(int i=1;i<len;++i){
int j=f[i];
while(j&&p[j]!=p[i])j=f[j];
f[i+1]= p[i]==p[j]?j+1:0;
}
}
int kmp(char *s,char *p){
int lenp=strlen(p);
int lens=strlen(s);
getfail(p);
int j=0;
for(int i=0;i<lens;++i){
while(j&&s[i]!=p[j])j=f[j];
if(s[i]==p[j])j++;
if(j==lenp)return 1;
}
return 0;
}
char *pos[N];
char str[N*100];
char *s;
int main(){
//ree
int T;sf("%d",&T);
while(T--){
sf("%d",&n);
char *o=str;
int fg=1;
int maxlen=0;
for(int i=1;i<=n;++i){
sf("%s",o);
int len=strlen(o);
if(len>maxlen){
maxlen=len;
s=o;
}
pos[i]=o;
o+=strlen(o)+2;
}
for(int i=1;i<=n;++i){
if(!kmp(s,pos[i])){
fg=0;break;
}
}
if(fg)puts(s);
else puts("No");
}
}
hash
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100000 + 10;
struct Hash
{
static const ll key = 137;
ll H[MAXN], xp[MAXN];
void init(const char s[], int len)
{
H[len] = 0;
for(int i = len - 1; i >= 0; i--)
H[i] = H[i + 1] * key + s[i];
xp[0] = 1;
for(int i = 1; i <= len; i++)
xp[i] = xp[i - 1] * key;
}
ll get(int pos, int len)
{
return H[pos] - H[pos + len] * xp[len];
}
}ha;
char buf[MAXN];
ll H[MAXN];
vector<int> F[256];
char fst[MAXN];
int L[MAXN];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
string str;
int select = -1;
for(int i = 0; i < n; ++i)
{
scanf("%s", buf);
int l = strlen(buf);
fst[i] = buf[0];
L[i] = l;
if(str.size() < l)
{
str = buf;
select = i;
}
ll h = 0;
for(int i = l - 1; i >= 0; --i) h = h * 137LL + buf[i];
H[i] = h;
}
ha.init(str.c_str(), str.size());
for(char c = 'a'; c <= 'z'; ++c) F[c].clear();
for(int i = 0; i < str.size(); ++i) F[str[i]].push_back(i);
bool ok = true;
for(int i = 0; i < n && ok; ++i)
{
if(i == select) continue;
ok = false;
for(auto p : F[fst[i]])
{
if(p + L[i] <= str.size() && ha.get(p, L[i]) == H[i]) {
ok = true;
break;
}
}
}
if(ok)
puts(str.c_str());
else
puts("No");
}
return 0;
}