题目描述
奶牛 Bessie 很喜欢用手机上网聊天,但她的蹄子太大,经常会按到好几个键造成不必要的麻烦(丢死人了,你下辈子还是不要当奶牛了)。于是 Farmer John 给她专门设计了一套「自动完成 APP」。这个 APP 能够连接到在线词典来获取词库(词库的来源是 Bessie 常用的 n 个单词),并且有着自动补全的功能。当 Bessie 想打出她的一个常用单词时,她只需输入这个单词的某个前缀,并询问词库中拥有这个前缀的字典序第 k 小的单词,APP 就会返回这是词库中的第几个单词。
Farmer John 是个大忙人,所以编写 APP 的任务自然就交给了你。输入
第一行两个整数 n,m,表示词库的单词个数和 Bessie 的询问次数。
接下来 n 行,每行一个字符串,表示 Bessie 的常用单词,输入的第 i 个字符串在词库中编号为 i。
接下来 m 行,每行一个整数 k 和一个字符串 S,表示 Bessie 的询问,意义是询问词库中以 S 为前缀的字典序第 k 小的单词在词库中的编号。输出
对于每次询问输出一个整数,表示以S为前缀的字典序第 k 小的单词在词库中的编号;如果不存在这样的单词,输出 −1。
看到题,一股字典树的套路感觉....于是敲了一个字典树,可惜T了
后来看题解,发现对于第k小字典序,可以先dfs整颗字典树,给每个串标号,然后在字典树走完串后直接输出下面的第k小即可.....
#include<bits/stdc++.h>
using namespace std;
#define Sheryang main
const int maxn=1e6+7;
typedef long long ll;
const int mod=1e9+7;
//#define getchar()(p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
//char buf[(1 << 21) + 1], *p1 = buf, *p2 = buf;
#define IO cin.tie(0),ios::sync_with_stdio(false);
#define pi acos(-1)
#define PII pair<ll,ll>
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
#define read read()
/** keep hungry and keep calm! **/
struct node{
int son[26],sz,end,id;
int l,r;
}tire[maxn];
int tot = 1;
void ins(char *s,int id){
int root = 1;
tire[root].sz ++;
for(int i=0;s[i];i++){
int u = s[i] - 'a';
if(tire[root].son[u] == 0){
tire[root].son[u] = ++tot;
}
root = tire[root].son[u];
tire[root].sz ++;
}
tire[root].end ++;
tire[root].id = id;
}
int ans[maxn],cnt;
void dfs(int u){
tire[u].l = cnt;
if(tire[u].end){
ans[cnt++] = tire[u].id;
}
for(int i=0;i<26;i++){
if(tire[u].son[i]){
dfs(tire[u].son[i]);
}
}
}
int solve(char *s,int k){
int root = 1;
for(int i=0;s[i];i++){
int u = s[i] -'a';
root = tire[root].son[u];
}
if(tire[root].sz < k) return -1;
return ans[tire[root].l + k -1];
}
char s[maxn];
int Sheryang(){
int n = read , Q = read;
for(int i=1;i<=n;i++){
scanf("%s",s);
ins(s,i);
}
dfs(1);
while(Q--){
int k = read;
scanf("%s",s);
printf("%d\n",solve(s,k));
}
return 0;
}