云神出的题= =,逼得蒟蒻要跳楼了
这道题的话。。。先把读入的字符串反转,然后建trie树
发现一个字符串的kpm串就是他的结尾字符的子树,于是对所有是字符串结尾的点按照dfs序展成一个序列。
问题转化为求区间第k大,用主席树什么的就好了。。。
1 /************************************************************** 2 Problem: 3439 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:1500 ms 7 Memory:62744 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <vector> 13 #include <algorithm> 14 15 using namespace std; 16 typedef vector <int> Vec; 17 const int N = 100005; 18 const int Len = 300005; 19 const int M = 2000005; 20 21 struct trie_node { 22 int son[26], st, ed; 23 Vec tail; 24 } t[Len]; 25 26 struct seg_node { 27 int lson, rson, num; 28 } tr[M]; 29 30 int n, cnt_trie = 1, cnt_seq, cnt_seg; 31 int Tail[N], root[N]; 32 char st[Len]; 33 int len; 34 inline void read() { 35 char ch = getchar(); 36 while (ch < 'a' || 'z' < ch) ch = getchar(); 37 len = 0; 38 while ('a' <= ch && ch <= 'z') 39 st[++len] = ch, ch = getchar(); 40 } 41 42 #define ch(j) (int) st[j] - 'a' 43 void build_trie() { 44 int i, j, now; 45 for (i = 1; i <= n; ++i) { 46 read(); 47 reverse(st + 1, st + len + 1); 48 now = 1; 49 for (j = 1; j <= len; ++j) { 50 if (!t[now].son[ch(j)]) 51 t[now].son[ch(j)] = ++cnt_trie; 52 now = t[now].son[ch(j)]; 53 } 54 Tail[i] = now, t[now].tail.push_back(i); 55 } 56 } 57 58 #define mid (l + r >> 1) 59 void insert(int &p, int l, int r, int pos) { 60 tr[++cnt_seg] = tr[p], p = cnt_seg, ++tr[p].num; 61 if (l == r) return; 62 if (pos <= mid) insert(tr[p].lson, l, mid, pos); 63 else insert(tr[p].rson, mid + 1, r, pos); 64 } 65 66 int query(int i, int j, int rank) { 67 i = root[i - 1], j = root[j]; 68 if (tr[j].num - tr[i].num < rank) return -1; 69 int l = 1, r = n; 70 while (l != r) { 71 if (tr[tr[j].lson].num - tr[tr[i].lson].num >= rank) 72 r = mid, i = tr[i].lson, j = tr[j].lson; 73 else { 74 rank -= tr[tr[j].lson].num - tr[tr[i].lson].num; 75 l = mid + 1, i = tr[i].rson, j = tr[j].rson; 76 } 77 } 78 return l; 79 } 80 81 void dfs(int p) { 82 int i, sz = t[p].tail.size(); 83 if (sz) { 84 t[p].st = ++cnt_seq, root[cnt_seq] = root[cnt_seq - 1]; 85 for (i = 0; i < sz; ++i) 86 insert(root[cnt_seq], 1, n, t[p].tail[i]); 87 } 88 for (i = 0; i < 26; ++i) 89 if (t[p].son[i]) 90 dfs(t[p].son[i]); 91 if (sz) 92 t[p].ed = cnt_seq; 93 } 94 95 int main() { 96 int i, x; 97 scanf("%d ", &n); 98 build_trie(); 99 dfs(1); 100 for (i = 1; i <= n; ++i) { 101 scanf("%d", &x); 102 printf("%d ", query(t[Tail[i]].st, t[Tail[i]].ed, x)); 103 } 104 }