码迷,mamicode.com
首页 > 其他好文 > 详细

P3975 [TJOI2015]弦论

时间:2019-10-25 20:10:32      阅读:50      评论:0      收藏:0      [点我收藏+]

标签:span   i++   namespace   memcpy   oid   http   eof   lse   its   

P3975 [TJOI2015]弦论

在原串所有子串中求字典序第k大的子串

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e6+5;
 4 char s[maxn];
 5 int a[maxn], c[maxn], size[maxn], sum[maxn], k, t;
 6 struct SuffixAutoMaton {
 7     int last, cnt;
 8     int ch[maxn*2][26], fa[maxn*2], len[maxn*2];
 9     void ins(int c) {
10         int p = last, np = ++cnt;
11         last = np; len[np] = len[p]+1;
12         for (;p && !ch[p][c]; p = fa[p]) ch[p][c] = np;
13         if (!p) fa[np] = 1;
14         else {
15             int q = ch[p][c];
16             if (len[p]+1 == len[q]) fa[np] = q;
17             else {
18                 int nq = ++cnt;
19                 len[nq] = len[p]+1;
20                 memcpy(ch[nq],ch[q],sizeof(ch[q]));
21                 fa[nq] = fa[q]; fa[q] = fa[np] = nq;
22                 for (; ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
23             }
24         }
25         size[np] = 1;
26     }
27     void build() {
28         scanf("%s",s+1);
29         int lens = strlen(s+1);
30         last = cnt = 1;
31         for (int i = 1; i <= lens; i++) ins(s[i]-a);
32     }
33     void work() {
34         for (int i = 1; i <= cnt; i++) c[len[i]]++;
35         for (int i = 1; i <= cnt; i++) c[i] += c[i-1];
36         for (int i = 1; i <= cnt; i++) a[c[len[i]]--] = i;
37         for (int i = cnt; i; i--) {
38             int p = a[i];
39             if (t == 1) size[fa[p]] += size[p];
40             else size[p] = 1;
41         }
42         size[1] = 0;
43         for (int i = cnt; i; i--) {
44             sum[a[i]] = size[a[i]];
45             for (int j = 0; j < 26; j++) {
46                 if (ch[a[i]][j]) sum[a[i]] += sum[ch[a[i]][j]];
47             }
48         }
49     }
50     void solve() {
51         if (k > sum[1]) {
52             puts("-1");
53             return;
54         }
55         int now = 1;
56         k -= size[now];
57         while (k > 0) {
58             int p = 0;
59             while (k > sum[ch[now][p]]) {
60                 k -= sum[ch[now][p]];
61                 p++;
62             }
63             now = ch[now][p];
64             putchar(a+p);
65             k -= size[now];
66         }
67         return;
68     }
69 }sam;
70 int main() {
71     sam.build();
72     scanf("%d%d",&t,&k);
73     sam.work();
74     sam.solve();
75     return 0;
76 }

 

P3975 [TJOI2015]弦论

标签:span   i++   namespace   memcpy   oid   http   eof   lse   its   

原文地址:https://www.cnblogs.com/wstong/p/11740358.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!