生活随笔
收集整理的這篇文章主要介紹了
SPOJ 7258 (后缀自动机)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載:http://hzwer.com/4492.html
給一個長度不超過90000的串S,每次詢問它的所有不同子串中,字典序第K小的,詢問不超過500個。
搞出后綴自動機
dp處理出每個點往下走能夠走出多少個串。
f[i]=sigma(f[ch[i][c])+1
這個可以按Max排序之后倒著推就好了。
詢問的時候看一下走下去個數是否<=k,是的話就走下去,然后–k;否則就找下一條邊
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
20 20
21 21
22 22
23 23
24 24
25 25
26 26
27 27
28 28
29 29
30 30
31 31
32 32
33 33
34 34
35 35
36 36
37 37
38 38
39 39
40 40
41 41
42 42
43 43
44 44
45 45
46 46
47 47
48 48
49 49
50 50
51 51
52 52
53 53
54 54
55 55
56 56
57 57
58 58
59 59
60 60
61 61
62 62
63 63
64 64
65 65
66 66
67 67
68 68
69 69
70 70
71 71
72 72
73 73
74 74
75 75
76 76
77 77
78 78
79 79
80 #include<iostream>
81 #include<cstdio>
82 #include<cstring>
83 #include<cstdlib>
84 #include<algorithm>
85 #include<cmath>
86 #define N 180005
87 #define inf 1000000000
88 using namespace std;
89 char ch[N];
90 int Q,p,q,np,nq;
91 int cnt=
1,last=
1,n;
92 int fa[N],to[N][
26],l[N],s[N];
93 int f[N],v[N];
94 void extend(
int c)
95 {
96 p=last;np=last=++cnt;l[np]=++
n;
97 for(;p&&!to[p][c];p=fa[p])to[p][c]=
np;
98 if(!p)fa[np]=
1;
99 else
100 {
101 int q=
to[p][c];
102 if(l[p]+
1==l[q])fa[np]=
q;
103 else
104 {
105 nq=++cnt;l[nq]=l[p]+
1;
106 memcpy(to[nq],to[q],
sizeof(to[q]));
107 fa[nq]=
fa[q];
108 fa[q]=fa[np]=
nq;
109 for(;to[p][c]==q;p=fa[p])to[p][c]=
nq;
110 }
111 }
112 }
113 void build()
114 {
115 scanf(
"%s",ch);
116 for(
char *c=ch;*c;c++)extend(*c-
'a');
117 }
118 void pre()
119 {
120 for(
int i=
1;i<=cnt;i++)v[l[i]]++
;
121 for(
int i=
1;i<=n;i++)v[i]+=v[i-
1];
122 for(
int i=
1;i<=cnt;i++)s[v[l[i]]--]=
i;
123 for(
int i=cnt;i;i--
)
124 {
125 f[s[i]]=
1;
126 for(
int j=
0;j<
26;j++
)
127 f[s[i]]+=
f[to[s[i]][j]];
128 }
129 }
130 void query()
131 {
132 p=
1;
int x;
133 scanf(
"%d",&
x);
134 while(x)
135 {
136 for(
int i=
0;i<
26;i++
)
137 if(to[p][i])
138 {
139 if(f[to[p][i]]>=
x)
140 {
141 putchar(
'a'+
i);
142 p=
to[p][i];
143 --x;
break;
144 }
145 else x-=
f[to[p][i]];
146 }
147 }
148 printf(
"\n");
149 }
150 int main()
151 {
152 build();
153 pre();
154 scanf(
"%d",&
Q);
155 while(Q--
)
156 query();
157 return 0;
158 }
?
轉載于:https://www.cnblogs.com/agenthtb/p/7696201.html
總結
以上是生活随笔為你收集整理的SPOJ 7258 (后缀自动机)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。