Sample Input
3 ab cb de 2 1 2 2 3 7 xabcd yabcd cdo cdp cdq cdr abcdz 1 1 2 3 aa aa aa 1 1 3
Sample Output
N N 1 3
题意:
给你n个字符串。每次询问给你x,y代表找出第x和y对字符串的【最长】相同后缀。
然后如果这n个字符串的前缀是这个后缀的话,就num++。输出num。
没有就是N,没有相同后缀也是N。
POINT:
后缀就是暴力找出来就好了。
然后把n个字符串放入字典树。查找即可。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
#define LL long long
const int maxn = 1e5+55;
string s[maxn];
int sz;
int tree[maxn*5][30];
int val[maxn*10];
void init()
{
memset(tree,0,sizeof tree);
sz=0;
memset(val,0,sizeof val);
}
void add(string a)
{
int l=(int)a.length();
int to = 0;
for(int i=0;i<l;i++){
int x = a[i]-'a';
if(tree[to][x]==0){
tree[to][x]=++sz;
}
to=tree[to][x];
val[to]++;
}
}
int find(char a[])
{
int to = 0;
int l=(int)strlen(a);
if(l==0) return 0;
for(int i=0;i<l;i++){
int x= a[i]-'a';
if(tree[to][x]==0){
return 0;
}
to=tree[to][x];
}
return val[to];
}
int main()
{
int n;
while(~scanf("%d",&n)){
init();
for(int i=1;i<=n;i++) {
cin>>s[i];
add(s[i]);
}
int q;
scanf("%d",&q);
while(q--){
int a,b;
scanf("%d %d",&a,&b);
int now=0;
int l1=s[a].length();
int l2=s[b].length();
char ss[maxn];
while(now<l1&&now<l2){
if(s[a][l1-now-1]==s[b][l2-now-1]){
now++;
}else
break;
}
//printf("%d",now);
if(now==0){
printf("N\n");
}else{
int ans = 0;
int len=0;
for(int i=l1-now;i<l1;i++){
ss[len++]=s[a][i];
}
ss[len++]=0;
for(int i=0;i<len;i++){
ans = find(ss+i);
if(ans!=0){
break;
}
}
if(ans==0){
printf("N\n");
}else{
printf("%d\n",ans);
}
}
}
}
}