Fleet of the Eternal ThroneTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1035 Accepted Submission(s): 480 Problem Description > The Eternal Fleet was built many centuries ago before the time of Valkorion by an unknown race on the planet of Iokath. The fate of the Fleet's builders is unknown but their legacy would live on. Its first known action was in the annihilation of all life in Wild Space. It spread across Wild Space and conquered almost every inhabited world within the region, including Zakuul. They were finally defeated by a mysterious vessel known as the Gravestone, a massive alien warship that countered the Eternal Fleet's might. Outfitted with specialized weapons designed to take out multiple targets at once, the Gravestone destroyed whole sections of the fleet with a single shot. The Eternal Fleet was finally defeated over Zakuul, where it was deactivated and hidden away. The Gravestone landed in the swamps of Zakuul, where the crew scuttled it and hid it away.
Input The first line of the input contains an integer T , denoting the number of test cases.
Output You should output the answers for the queries, one integer per line.
Sample Input 1 3 aaa baaa caaa 2 2 3 1 2
Sample Output 3 3 |
题意:
给你n个字符串,再给你q个询问,每次询问都给你两个字符串的下标,要你求出这两个字符串的最长公共前缀。
做法:
可以用AC自动机解决,再插入的时候就可以对该节点打上记号,这个点是这个单词的第几位,即如果匹配到这一位也是符合的,将会有多少个字符成为相同的前缀。在询问的时候跑一遍x,打上唯一的标记,再跑一次y字符,遇到相同标记的就记录最大的ans即可。
算是进阶吧,对ac自动机有了更多的理解吧。
#include<bits/stdc++.h>
using namespace std;
const int maxn=200005;
char s[maxn];
int pos[maxn],n;
struct Tire{
static const int NODENUM=(int)1e6+5,R=26;
int nxt[NODENUM][R],fail[NODENUM],flag[NODENUM],len[NODENUM];
int rt,tot;
int newnode(){
for(int i=0;i<R;i++)nxt[tot][i]=-1;
flag[tot]=0;
return tot++;
}
void init(){
tot=0;
rt=newnode();
memset(len,0,sizeof(len));
}
void insert(char *s){
int now=rt,lens=strlen(s);
for(int i=0;i<lens;i++){
int val=s[i]-'a';
if(nxt[now][val]==-1)nxt[now][val]=newnode();
len[nxt[now][val]]=len[now]+1;
now=nxt[now][val];
}
}
void build(){
queue<int>q;
fail[rt]=rt;
for(int i=0;i<R;i++){
if(nxt[rt][i]==-1)nxt[rt][i]=rt;
else {
fail[nxt[rt][i]]=rt;
q.push(nxt[rt][i]);
}
}
while(!q.empty()){
int now=q.front();q.pop();
for(int i=0;i<R;i++){
if(nxt[now][i]==-1)nxt[now][i]=nxt[fail[now]][i];
else {
fail[nxt[now][i]]=nxt[fail[now]][i];
q.push(nxt[now][i]);
}
}
}
}
void update(char *s,int vis){
int now=rt,lens=strlen(s);
for(int i=0;i<lens;i++){
int val=s[i]-'a';
now=nxt[now][val];
int tmp=now;
while(tmp!=rt){
flag[tmp]=vis;
tmp=fail[tmp];
}
}
}
int query(char *s,int vis){
int now=rt,ans=0,lens=strlen(s);
for(int i=0;i<lens;i++){
int val=s[i]-'a';
now=nxt[now][val];
int tmp=now;
while(tmp!=rt){
if(flag[tmp]==vis){
ans=max(ans,len[tmp]);
}
tmp=fail[tmp];
}
}
return ans;
}
}ac;
int main(){
int t,q,fl,x,y;
cin>>t;
while(t--){
fl=0;
ac.init();
int d=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
pos[i]=d;
scanf("%s",s+d);
ac.insert(s+d);
d+=strlen(s+d)+1;
}
ac.build();
scanf("%d",&q);
while(q--){
scanf("%d%d",&x,&y);
ac.update(s+pos[x],++fl);
int ans=ac.query(s+pos[y],fl);
printf("%d\n",ans);
}
}
return 0;
}