倒着建trie,然后主席树来求子树第k大。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define maxn 300500 using namespace std; int n,trie[maxn][27],fath[maxn],cnt=0,tag[maxn],k,rot,kr,dfn[maxn],mx[maxn],times=0,line[maxn]; int tot=0,ls[maxn<<3],rs[maxn<<3],sum[maxn<<3]; char s[maxn]; vector <int> v[maxn],root[maxn]; void insert(int father,int &now,int l,int x) { if (!now) {now=++cnt;fath[now]=father;} if (!l) {tag[x]=now;v[now].push_back(x);return;} insert(now,trie[now][s[l-1]-'a'+1],l-1,x); } void build(int &now,int left,int right) { now=++tot; if (left==right) return; int mid=left+right>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); } void modify(int last,int &now,int left,int right,int pos) { now=++tot;sum[now]=sum[last]+1; if (left==right) return; int mid=left+right>>1; ls[now]=ls[last];rs[now]=rs[last]; if (pos<=mid) modify(ls[last],ls[now],left,mid,pos); else modify(rs[last],rs[now],mid+1,right,pos); } int ask(int last,int now,int left,int right,int x) { if (sum[now]-sum[last]<x) return -1; if (left==right) return left; int mid=left+right>>1,lsum=sum[ls[now]]-sum[ls[last]]; if (x<=lsum) return ask(ls[last],ls[now],left,mid,x); else return ask(rs[last],rs[now],mid+1,right,x-lsum); } void dfs(int now) { dfn[now]=mx[now]=++times;line[times]=now; for (int i=1;i<=26;i++) { if (trie[now][i]) { dfs(trie[now][i]); mx[now]=max(mx[now],mx[trie[now][i]]); } } } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%s",s); insert(0,rot,strlen(s),i); } dfs(rot); build(kr,1,n);root[0].push_back(1); for (int i=1;i<=times;i++) { int now=line[i]; if (!v[now].size()) root[i].push_back(root[i-1][root[i-1].size()-1]); else { root[i].push_back(tot+1);modify(root[i-1][root[i-1].size()-1],kr,1,n,v[now][0]); for (int j=1;j<v[now].size();j++) { root[i].push_back(tot+1); modify(root[i][j-1],kr,1,n,v[now][j]); } } } for (int i=1;i<=n;i++) { scanf("%d",&k); int ret=tag[i]; printf("%d\n",ask(root[dfn[ret]-1][root[dfn[ret]-1].size()-1],root[mx[ret]][root[mx[ret]].size()-1],1,n,k)); } return 0; }