云神出的题= =,逼得蒟蒻要跳楼了

这道题的话。。。先把读入的字符串反转,然后建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", &n);
 98     build_trie();
 99     dfs(1);
100     for (i = 1; i <= n; ++i) {
101         scanf("%d", &x);
102         printf("%d\n", query(t[Tail[i]].st, t[Tail[i]].ed, x));
103     }
104 }
View Code

 

posted on 2014-12-01 16:42  Xs酱~  阅读(200)  评论(0编辑  收藏  举报