Skip to content

Commit bd4cdc3

Browse files
authored
string, SA, djs
1 parent 0602978 commit bd4cdc3

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

algospot/HABIT.cpp

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//category : string, SA, djs
2+
3+
#include <iostream>
4+
#include <string>
5+
#include <vector>
6+
#include <algorithm>
7+
#define pii pair<int,int>
8+
using namespace std;
9+
int g[4001];
10+
int lcp[4001];
11+
int tmp[4001];
12+
int s_ix[4001];
13+
int p[4001];
14+
int sz[4001];
15+
bool cover[4001];
16+
int d;
17+
bool cmp(int a, int b){
18+
if (g[a] != g[b]) return g[a] < g[b];
19+
return g[a + d] < g[b + d];
20+
}
21+
int find(int a){
22+
if (a != p[a]) p[a] = find(p[a]);
23+
return p[a];
24+
}
25+
void join(int a, int b){
26+
a = find(a);
27+
b = find(b);
28+
if (a == b) return;
29+
p[b] = a;
30+
sz[a] += sz[b];
31+
}
32+
int main(){
33+
int i, j;
34+
int C;
35+
int K;
36+
int ans;
37+
string s;
38+
cin >> C;
39+
while (C--){
40+
cin >> K >> s;
41+
if (K == 1){
42+
cout << s.size() << "\n";
43+
continue;
44+
}
45+
for (i = 0; i < s.size(); i++){
46+
s_ix[i] = i;
47+
g[i] = s[i];
48+
cover[i] = false;
49+
p[i] = i;
50+
sz[i] = 0;
51+
}
52+
ans = 0;
53+
g[i] = -1;
54+
cover[i] = false;
55+
d = 1;
56+
do{
57+
sort(s_ix, s_ix + s.size(), cmp);
58+
tmp[s_ix[0]] = 0;
59+
for (i = 1; i < s.size(); i++)
60+
tmp[s_ix[i]] = tmp[s_ix[i - 1]] + cmp(s_ix[i - 1], s_ix[i]);
61+
for (i = 0; i < s.size(); i++)
62+
g[i] = tmp[i];
63+
d <<= 1;
64+
} while (s.size() - 1 != g[s_ix[s.size() - 1]]);
65+
d = 0;
66+
vector<pii > v;
67+
for (i = 0; i < s.size(); i++){
68+
if (g[i] == 0) continue;
69+
j = s_ix[g[i] - 1];
70+
d = max(d - 1, 0);
71+
lcp[g[i]] = 0;
72+
while (i + d < s.size() && j + d < s.size() && s[j + d] == s[i + d])
73+
lcp[g[i]] = ++d;
74+
d = lcp[g[i]] - 1;
75+
//cout << lcp[g[i]] << "," << i << endl;
76+
if (lcp[g[i]] > 0){
77+
sz[g[i]] = 1;
78+
v.push_back({lcp[g[i]],g[i]});
79+
}
80+
}
81+
sort(v.begin(), v.end());
82+
while (!v.empty()){
83+
i = v.back().second;
84+
if (cover[i - 1]) join(i - 1, i);
85+
if (cover[i + 1]) join(i, i+1);
86+
//cout << sz[find(i)] << ","<<v.back().first << endl;
87+
if (sz[find(i)] + 1 >= K){
88+
ans = v.back().first;
89+
break;
90+
}
91+
cover[i] = true;
92+
v.pop_back();
93+
}
94+
cout << ans << "\n";
95+
}
96+
97+
return 0;
98+
}

0 commit comments

Comments
 (0)