题意:给出n(<=1e5)个串(总长度<=1e5),以及q(<=300,数据有点弱,q改成1e5才好)次询问,每次询问给出x和y,表示输入的第x个和第y个串,要求找出一个最长的字串p,满足:p是x的字串,p是y的字串,且p是这n个串中某一个(可以是多个)的前缀,输出这个最大的长度。
参考http://blog.youkuaiyun.com/wubaizhe/article/details/77431875
果然对于ac自动机一点都不熟。居然找了那么久才找到sb错误。。。
收货:
- 可以把所以的字符串都放到一个长的s中,只要有pos标记就可以了。。然后+len+1来切断。。
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
#include<iomanip>
#include<cstdio>
#include<stack>
#include<iostream>
#include<map>
#include<queue>
#include<cmath>
#include<strstream>
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 N 1000150
#define M 200020
#define mod 998244353
#define ULL unsigned long long
#define LL long long
#define inf 0x3f3f3f3f
//freopen("in.txt","r",stdin);
//2017年08月21日10:35:07 15min
int pos[N];
int dep[N];
char s[N];
int id[N];
struct Trie {
int next[N][26],fail[N<<2];
int col[N];
int root,L;
int newnode() {
for(int i = 0;i < 26;i++)
next[L][i] = -1;
L++;
return L-1;
}
inline int ID(char s){return s-'a';}
void init() {
mem(col,-1);
L = 0;
root = newnode();
}
void insert(char buf[]) {
int len = strlen(buf);
int now = root;
for(int i = 0;i < len;i++) {
int id=ID(buf[i]);
if(next[now][id] == -1){
next[now][id] = newnode();
dep[next[now][id]]=i+1;
}
now = next[now][id];
}
}
void build() {
queue<int>Q;
fail[root] = root;
for(int i = 0;i < 26;i++)
if(next[root][i] == -1)
next[root][i] = root;
else {
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while( !Q.empty() ) {
int now = Q.front(); Q.pop();
for(int i = 0;i < 26;i++)
if(next[now][i] == -1)
next[now][i] = next[fail[now]][i];
else {
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
int query(char *s,int x,bool sta){
int len=strlen(s),u=root,ans=0;
for(int i=0;i<len;++i){
int id=ID(s[i]);
u=next[u][id];
int tmp=u;
while(tmp){
if(!sta)col[tmp]=x;
else if(col[tmp]==x)ans=max(ans,dep[tmp]);
tmp=fail[tmp];
}
}
return ans;
}
}ac;
int main(){
//freopen("in.txt","r",stdin);
int T;sf("%d",&T);
while(T--){
ac.init();
int n;sf("%d",&n);
int now=0;
rep(i,1,n){
pos[i]=now;
sf("%s",s+now);
ac.insert(s+now);
int len=strlen(s+now);
now+=len+1;
}
ac.build();
int q;sf("%d",&q);
while(q--){
int x,y;sf("%d%d",&x,&y);
ac.query(s+pos[x],q,0);
int ans=ac.query(s+pos[y],q,1);
pf("%d\n",ans);
}
}
}