1
- #include < bits/stdc++.h>
1
+ #include < bits/stdc++.h>
2
+
2
3
using namespace std ;
3
- #define FOR (i,a,b ) for (int i = (a); i <= (b); ++i)
4
- #define FORD (i,a,b ) for (int i = (a); i >= (b); --i)
5
- #define pb push_back
6
- #define pocz first
7
- #define kon second.first
8
- #define poz second.second
9
- typedef long long ll;
10
- typedef long double ld;
11
- typedef pair<int , int > pii;
4
+
12
5
const int N = 1e6 + 2 ;
13
6
const int R = 23 ;
14
7
15
- pair<int ,pii > A[N];
8
+ pair<int , pair< int , int > > A[N];
16
9
int KMR[N][R];
10
+
17
11
void kmr (string s) {
18
- int n = s.size () - 1 ;
19
- int r = log2 (n) + 1 , pot = 1 ;
20
- FOR (i, 1 , n) {
21
- KMR[i][0 ] = s[i] - ' a' + 1 ;
12
+ int n = s.size () - 1 ;
13
+ int r = log2 (n) + 1 , pot = 1 ;
14
+
15
+ for (int i = 1 ; i <= n; i++) {
16
+ KMR[i][0 ] = s[i] - ' a' + 1 ;
17
+ }
18
+
19
+ for (int k = 1 ; k <= r; k++) {
20
+ for (int i = 1 ; i <= n; i++) {
21
+ if (i + pot > n)
22
+ A[i] = {KMR[i][k - 1 ], {-1 , i}};
23
+ else
24
+ A[i] = {KMR[i][k - 1 ], {KMR[i + pot][k - 1 ], i}};
22
25
}
23
- FOR (k, 1 , r) {
24
- FOR (i, 1 , n) {
25
- if (i + pot > n) A[i] = { KMR[i][k - 1 ], {-1 , i} };
26
- else A[i] = { KMR[i][k - 1 ], {KMR[i + pot][k - 1 ], i} };
27
- }
28
- sort (A + 1 , A + (n + 1 ));
29
- int kl = 0 ;
30
- pii p = {-1 ,-1 }, a; // poprzedni element
31
- FOR (i, 1 , n) {
32
- a = {A[i].pocz , A[i].kon };
33
- if (p != a) {
34
- p = a;
35
- ++kl;
36
- }
37
- KMR[A[i].poz ][k] = kl;
38
- }
39
- pot *= 2 ;
26
+ sort (A + 1 , A + (n + 1 ));
27
+ int kl = 0 ;
28
+ pair<int , int > p = {-1 , -1 }, a; // previous element
29
+ for (int i = 1 ; i <= n; i++) {
30
+ a = {A[i].first , A[i].second .first };
31
+ if (p != a) {
32
+ p = a;
33
+ ++kl;
34
+ }
35
+ KMR[A[i].second .second ][k] = kl;
40
36
}
41
- cout<<" KMR:\n " ; FOR (k, 0 , r) { FOR (i, 1 , n) cout<<KMR[i][k]<<" " ; cout<<" \n " ; } // wypisz tablice
37
+ pot *= 2 ;
38
+ }
39
+ cout << " KMR:\n " ;
40
+ for (int k = 0 ; k <= r; k++) {
41
+ for (int i = 1 ; i <= n; i++)
42
+ cout << KMR[i][k] << " " ;
43
+ cout << " \n " ;
44
+ }
42
45
}
43
46
44
- int SA[N], RANK[N]; // SA - przechowuje informacje o kolejnosci w SA, RANK - informuje ktory leksykograficznie jest ity sufiks
47
+ int SA[N], RANK[N]; // SA - przechowuje informacje o kolejnosci w SA, RANK -
48
+ // informuje ktory leksykograficznie jest ity sufiks
45
49
void sa (string s) { // suffix array
46
- int n = s.size () - 1 ;
47
- int r = log2 (n) + 1 ; // ostatnia warstwa KMR
48
- FOR (i, 1 , n) {
49
- SA[KMR[i][r]] = i;
50
- RANK[i] = KMR[i][r]; // RANK pomaga przy nawigacji po SA, jest to odwrotnosc SA
51
- }
52
- cout<<" SA:\n " ;
53
- FOR (i, 1 , n) {
54
- cout<<SA[i]<<" : " ;
55
- FOR (j, SA[i], n) cout<<s[j]; cout<<" \n " ;
56
- }
57
- cout<<" RANK:\n " ;
58
- FOR (i, 1 , n) cout<<RANK[i]<<" " ; cout<<" \n " ;
50
+ int n = s.size () - 1 ;
51
+ int r = log2 (n) + 1 ; // ostatnia warstwa KMR
52
+ for (int i = 1 ; i <= n; i++) {
53
+ SA[KMR[i][r]] = i;
54
+ RANK[i] =
55
+ KMR[i][r]; // RANK pomaga przy nawigacji po SA, jest to odwrotnosc SA
56
+ }
57
+ cout << " SA:\n " ;
58
+ for (int i = 1 ; i <= n; i++) {
59
+ cout << SA[i] << " : " ;
60
+ for (int j = SA[i]; j <= n; j++)
61
+ cout << s[j];
62
+ cout << " \n " ;
63
+ }
64
+ cout << " RANK:\n " ;
65
+ for (int i = 1 ; i <= n; i++)
66
+ cout << RANK[i] << " " ;
67
+ cout << " \n " ;
59
68
}
60
69
61
70
int LCP[N];
62
71
63
- int czescwspolna (string s, int a, int b) {
64
- int n = s.size () - 1 , i = 0 ;
65
- while (a + i <= n && b + i <= n) {
66
- if (s[a + i] != s[b + i]) break ;
67
- ++i;
68
- }
69
- return i;
72
+ int commonPart (string s, int a, int b) {
73
+ int n = s.size () - 1 , i = 0 ;
74
+ while (a + i <= n && b + i <= n) {
75
+ if (s[a + i] != s[b + i])
76
+ break ;
77
+ ++i;
78
+ }
79
+ return i;
70
80
}
71
81
72
82
void lcp (string s) { // longest common prefix
73
- int n = s.size () - 1 ;
74
- FOR (i, 1 , n) {
75
- if (RANK[i] == 1 ) LCP[1 ] = -1 ; // jezeli jest pierwszy leksykograficznie to -1 bo nie ma dla niego pary
76
- else LCP[RANK[i]] = czescwspolna (s, i, SA[RANK[i] - 1 ]);
77
- }
78
- cout<<" LCP:\n " ; FOR (i, 1 , n) cout<<LCP[i]<<" " ; cout<<" \n " ;
83
+ int n = s.size () - 1 ;
84
+ for (int i = 1 ; i <= n; i++) {
85
+ if (RANK[i] == 1 )
86
+ LCP[1 ] = -1 ; // jezeli jest pierwszy leksykograficznie to -1 bo nie ma dla
87
+ // niego pary
88
+ else
89
+ LCP[RANK[i]] = commonPart (s, i, SA[RANK[i] - 1 ]);
90
+ }
91
+ cout << " LCP:\n " ;
92
+ for (int i = 1 ; i <= n; i++)
93
+ cout << LCP[i] << " " ;
94
+ cout << " \n " ;
79
95
}
80
96
81
- int porownaj ( int a, int b, int c, int d) { // 0 - s(a,b) < s(c,d), 1 - s(a,b) == s(c,d), 2 - s(a,b) > s(c,d)
82
- int n = b - a + 1 , m = d - c + 1 , pot = 1 , pota = - 1 , potb = - 1 , qa, qb;
83
- bool oa = 0 , ob = 0 ;
84
- FOR (i, 2 , 20 ) {
85
- pot *= 2 ;
86
- if (pot > n && !oa ) {
87
- pota = pot / 2 ;
88
- qa = i - 2 ; // nie jestem pewny dlaczego i - 2, a nie i - 1
89
- oa = 1 ;
90
- }
91
- if (pot > m && !ob) {
92
- potb = pot / 2 ;
93
- qb = i - 2 ; // ^^^ (same here lulz)
94
- ob = 1 ;
95
- }
96
- if (pot > n && pot > m ) break ;
97
+ int compare (
98
+ int a, int b, int c,
99
+ int d) { // 0 - s(a,b) < s(c,d), 1 - s(a,b) == s(c,d), 2 - s(a,b) > s(c,d)
100
+ int n = b - a + 1 , m = d - c + 1 , pot = 1 , pota = - 1 , potb = - 1 , qa, qb;
101
+ bool oa = 0 , ob = 0 ;
102
+ for ( int i = 2 ; i <= 20 ; i++ ) {
103
+ pot *= 2 ;
104
+ if (pot > n && !oa) {
105
+ pota = pot / 2 ;
106
+ qa = i - 2 ; // nie jestem pewny dlaczego i - 2, a nie i - 1
107
+ oa = 1 ;
108
+ }
109
+ if (pot > m && !ob) {
110
+ potb = pot / 2 ;
111
+ qb = i - 2 ; // ^^^ (same here lulz)
112
+ ob = 1 ;
97
113
}
98
- pii x, y;
99
- x = {KMR[a][qa], KMR[b - pota + 1 ][qa]};
100
- y = {KMR[c][qb], KMR[d - potb + 1 ][qb]};
101
- if (x < y) return 0 ;
102
- else if (x == y) return 1 ;
103
- else return 2 ;
114
+ if (pot > n && pot > m)
115
+ break ;
116
+ }
117
+ pair<int , int > x, y;
118
+ x = {KMR[a][qa], KMR[b - pota + 1 ][qa]};
119
+ y = {KMR[c][qb], KMR[d - potb + 1 ][qb]};
120
+ if (x < y)
121
+ return 0 ;
122
+ else if (x == y)
123
+ return 1 ;
124
+ else
125
+ return 2 ;
104
126
}
105
127
106
128
signed main () {
107
- ios_base::sync_with_stdio (0 );
108
- cin.tie (0 );
109
- string s;
110
- cin>>s;
111
- // cin>>a>>b>>c>>d;
112
- s = " #" + s;
113
- kmr (s);
114
- sa (s);
115
- lcp (s);
116
- return 0 ;
117
- }
129
+ ios_base::sync_with_stdio (0 );
130
+ cin.tie (0 );
131
+ string s;
132
+ cin >> s;
133
+ s = " #" + s;
134
+ kmr (s);
135
+ sa (s);
136
+ lcp (s);
137
+ return 0 ;
138
+ }
0 commit comments