在每个给出的子串的起始位置打个标记,记录的是从这里开始的最长子串。
然后输出的时候就扫,如果遇到开始位置,就从这里开始输出,如果其后被更长的覆盖,就跳转到更长的串进行输出。
如果位置没被覆盖,就输出'a'。
#include<cstdio> #include<string> #include<algorithm> #include<iostream> using namespace std; string s[100010]; int n,m,p[2000010],len[100010],nn,now; void print(int x){ for(int i=x,j=0;j<len[p[x]];++i,++j){ if(!p[i] || i==x || len[p[i]]+j<=len[p[x]]){ putchar(s[p[x]][j]); now=max(now,i); } else{ print(i); break; } } } int main(){ int x; scanf("%d",&n); for(int i=1;i<=n;++i){ cin>>s[i]>>m; len[i]=s[i].length(); for(int j=1;j<=m;++j){ scanf("%d",&x); if(len[i]>len[p[x]]){ p[x]=i; nn=max(nn,x+len[i]-1); } } } for(int i=1;i<=nn;){ if(p[i]){ print(i); i=now+1; } else{ putchar('a'); ++i; } } puts(""); return 0; }