洛谷P2237 [USACO14FEB]自动完成Auto-complete
Trie树
1 #include <bits/stdc++.h> 2 #define For(i, j, k) for(int i=j; i<=k; i++) 3 #define Dow(i, j, k) for(int i=j; i>=k; i--) 4 #define LL long long 5 using namespace std; 6 inline int read() { 7 int x = 0, f = 1; 8 char ch = getchar(); 9 while(ch<'0'||ch>'9') { if(ch=='-') f = -1; ch = getchar(); } 10 while(ch>='0'&&ch<='9') { x = x*10+ch-48; ch = getchar(); } 11 return x * f; 12 } 13 void write(int x) { 14 if(x<0) putchar('-'), x=-x; 15 if(x>9) write(x/10); 16 putchar(x%10+48); 17 } 18 void writeln(int x) { write(x); puts(""); } 19 20 const int N = 1000011; 21 int n, tot, K, Q; 22 int son[N][26], siz[N], to[N]; 23 char ch[N]; 24 25 inline void insert(int id, char ch[]) { 26 int now = 0; 27 int len = strlen(ch+1); 28 For(i, 1, len) { 29 if(!son[now][ch[i]-'a']) son[now][ch[i]-'a'] = ++tot; 30 now = son[now][ch[i]-'a']; ++siz[now]; 31 } 32 to[now] = id; 33 } 34 35 inline int Query(int K, char ch[]) { 36 int now = 0; 37 int len = strlen(ch+1); 38 For(i, 1, len) { 39 if(!son[now][ch[i]-'a']) return -1; 40 now = son[now][ch[i]-'a']; 41 } 42 if(siz[now] < K) return -1; 43 while(1) { 44 if(to[now] && K==1) return to[now]; 45 if(to[now]) --K; 46 For(i, 0, 25) 47 if(siz[son[now][i]] < K) 48 K -= siz[son[now][i]]; 49 else { 50 now = son[now][i]; 51 break; 52 } 53 } 54 } 55 56 int main() { 57 n = read(); Q = read(); 58 For(i, 1, n) { 59 scanf("%s", ch+1); 60 insert(i, ch); 61 } 62 while(Q--) { 63 K = read(); 64 scanf("%s", ch+1); 65 writeln(Query(K, ch)); 66 } 67 return 0; 68 }