【分析】
建一棵Trie树,然后基本上就是一个裸的Trie了,记录一下父亲节点和是否是快捷方式即可。
【代码】
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=500010,inf=~0U>>1;
struct Trie
{
int ch[maxn][27],fa[maxn];
char chi[maxn],temp[maxn];
int length[maxn];
int To[maxn];
int cnt;
int d(char chx) {if (chx=='/') return 26;return chx-'a';}
Trie() {cnt=1;chi[1]='/';}
int Get_Seq(char* s)
{
int len=strlen(s),now=1;
s[len]='/';
if (len==1) return 1;
for (int l=1,r=1;r<len;l=r=(r+1))
{
while (r<len && s[r]!='/') r++;
for (int i=l;i<=r;now=ch[now][d(s[i++])]) if (!ch[now][d(s[i])])
fa[++cnt]=now,chi[cnt]=s[i],ch[now][d(s[i])]=cnt;
length[now]=r-l;
while (To[now]) now=To[now];
}
return now;
}
void ShortCut(char* s,char* t) {To[Get_Seq(s)]=Get_Seq(t);}
void RealWay(char* s)
{
int sid=Get_Seq(s);
int tot=0;
if (sid==1) temp[tot++]='/';
while (sid) temp[tot++]=chi[sid],sid=fa[sid];
while (--tot) putchar(temp[tot]);
putchar('\n');
}
}T;
char a[maxn],b[maxn];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
while (n--) scanf("%s %s",a,b),T.ShortCut(a,b);
while (m--) scanf("%s",a),T.RealWay(a);
return 0;
}