挺好想的
trie建树后,按dfn序建可持久化
注意:计数变量多的题目一定要注意检查会不会用的时候搞混了
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long LL;
const int M=300007;
const int N=2000007;
inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=0;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f?x:-x;
}
int n,tot;
char s[M];
int ch[M][26];
int g[M],td;
struct edge{int y,next;}e[M];
int st[M],ed[M],pid[M],dfn;
int root[M],cnt;
int pt[M];
struct node{
int c[2],sz;
node(){c[0]=c[1]=sz=0;}
}a[N];
void ins(int ii){
scanf("%s",s+1);
int x=0,i,k,len=strlen(s+1);
for(i=len;i>0;i--){
k=s[i]-'a';
if(ch[x][k])x=ch[x][k];
else x=ch[x][k]=++tot;
}
e[++td].y=ii;e[td].next=g[x];g[x]=td;
pt[ii]=x;
}
void dfs(int x){
if(g[x]) st[x]=++dfn,pid[dfn]=x;
for(int i=0;i<26;i++) if(ch[x][i]) dfs(ch[x][i]);
if(g[x]) ed[x]=dfn;
}
int cpynode(int x){
a[++cnt]=a[x];
a[cnt].sz++;
return cnt;
}
int ins(int rt,int l,int r,int to){
int x=cpynode(rt);
if(l==r) return x;
int mid=l+r>>1;
if(to<=mid)a[x].c[0]=ins(a[rt].c[0],l,mid,to);
else a[x].c[1]=ins(a[rt].c[1],mid+1,r,to);
return x;
}
int get(int lt,int rt,int l,int r,int to){
if(l==r) return l;
int mid=l+r>>1;
int num=a[a[rt].c[0]].sz-a[a[lt].c[0]].sz;
if(to<=num) return get(a[lt].c[0],a[rt].c[0],l,mid,to);
else return get(a[lt].c[1],a[rt].c[1],mid+1,r,to-num);
}
int main(){
int i,p,x,y;
n=rd();
for(i=1;i<=n;i++) ins(i);
dfs(0);
for(i=1;i<=dfn;i++){
root[i]=root[i-1];
x=pid[i];
for(p=g[x];p;p=e[p].next)
root[i]=ins(root[i],1,n,e[p].y);
}
for(i=1;i<=n;i++){
p=rd();
x=pt[i];
y=a[root[ed[x]]].sz-a[root[st[x]-1]].sz;
if(p>y||p<=0) puts("-1");
else printf("%d\n",get(root[st[x]-1],root[ed[x]],1,n,p));
}
return 0;
}