| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 
 | 
 
 
 
 
 
 
 #include <bits/stdc++.h>
 using namespace std;
 #define int long long
 #define resetIO(x) \
 freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout)
 #define debug(fmt, ...) \
 fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
 template <class _Tp>
 inline _Tp& read(_Tp& x) {
 bool sign = false;
 char ch = getchar();
 long double tmp = 1;
 for (; !isdigit(ch); ch = getchar())
 sign |= (ch == '-');
 for (x = 0; isdigit(ch); ch = getchar())
 x = x * 10 + (ch ^ 48);
 if (ch == '.')
 for (ch = getchar(); isdigit(ch); ch = getchar())
 tmp /= 10.0, x += tmp * (ch ^ 48);
 return sign ? (x = -x) : x;
 }
 template <class _Tp>
 inline void write(_Tp x) {
 if (x < 0)
 putchar('-'), x = -x;
 if (x > 9)
 write(x / 10);
 putchar((x % 10) ^ 48);
 }
 const int MAXN = 3e3 + 10;
 const int LOGN = 15;
 const int INF = 0x3f3f3f3f3f3f3f3f;
 struct SuffixArray {
 int n, sa[MAXN], rk[MAXN], tp[MAXN], ht[MAXN], he[MAXN];
 void radix_sort(int m) {
 static int buc[MAXN];
 for (int i = 0; i <= m; ++i)
 buc[i] = 0;
 for (int i = 1; i <= n; ++i)
 buc[rk[i]]++;
 for (int i = 1; i <= m; ++i)
 buc[i] += buc[i - 1];
 for (int i = n; i >= 1; --i)
 sa[buc[rk[tp[i]]]--] = tp[i];
 }
 void init(int n, char* s) {
 this->n = n;
 int m = 100;
 for (int i = 1; i <= n; ++i)
 rk[i] = s[i] - '0' + 1, tp[i] = i;
 radix_sort(m);
 for (int w = 1, p = 0; p < n; m = p, w <<= 1) {
 p = 0;
 for (int i = 1; i <= w; ++i)
 tp[++p] = n - w + i;
 for (int i = 1; i <= n; ++i)
 if (sa[i] > w)
 tp[++p] = sa[i] - w;
 radix_sort(m);
 copy(rk + 1, rk + n + 1, tp + 1);
 rk[sa[1]] = p = 1;
 for (int i = 2; i <= n; ++i) {
 if (tp[sa[i - 1]] == tp[sa[i]] && tp[sa[i - 1] + w] == tp[sa[i] + w])
 rk[sa[i]] = p;
 else
 rk[sa[i]] = ++p;
 }
 }
 for (int i = 1, k = 0; i <= n; ++i) {
 if (k)
 k--;
 while (s[i + k] == s[sa[rk[i] - 1] + k])
 k++;
 ht[i] = k;
 }
 for (int i = 1; i <= n; ++i)
 he[i] = ht[sa[i]];
 }
 } sa;
 int n, lg2[MAXN], st[MAXN][LOGN];
 char str[MAXN];
 int lcs(int l, int r) {
 if (l == r)
 return INF;
 int k = lg2[r - l];
 return min(st[l + 1][k], st[r - (1 << k) + 1][k]);
 }
 signed main() {
 read(n);
 scanf("%s", str + 1);
 sa.init(n, str);
 for (int i = 2; i <= n; ++i)
 lg2[i] = (i & (i - 1)) ? lg2[i - 1] : lg2[i - 1] + 1;
 for (int i = 1; i <= n; ++i)
 st[i][0] = sa.he[i];
 for (int j = 1; j < LOGN; ++j) {
 for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
 st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
 }
 }
 for (int i = 1; i <= n; ++i) {
 int mn = sa.he[i] + 1, mx = n - sa.sa[i] + 1;
 for (int j = mn; j <= mx; ++j) {
 int l = i, r = n, x = i;
 while (l <= r) {
 int mid = (l + r) >> 1;
 if (lcs(i, mid) >= j)
 l = mid + 1, x = mid;
 else
 r = mid - 1;
 }
 if (x != i)
 write(x - i + 1), putchar('\n');
 }
 }
 return 0;
 }
 
 |