1 2 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
| #include <cstdio> #include <cstring> #include <algorithm> #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) #define G(x) ((x) < tb ? (x) * 3 + 1 : ((x) - tb) * 3 + 2) using namespace std; const int N = 3*(1e5+5); int wa[N], wb[N], ws[N], wv[N], sa[N]; int rak[N], height[N], cal[N],n; char s[N],ans[N],s1[N]; int cnt[N]; int c0(int *r, int a, int b) { return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2]; } int c12(int k, int *r, int a, int b) { if (k == 2) return r[a] < r[b] || r[a] == r[b] && c12(1, r, a + 1, b + 1); return r[a] < r[b] || r[a] == r[b] && wv[a + 1] < wv[b + 1]; } void Rsort(int *r, int *a, int *b, int n, int m) { for (int i = 0; i < n; i++) wv[i] = r[a[i]]; for (int i = 0; i < m; i++) ws[i] = 0; for (int i = 0; i < n; i++) ws[wv[i]]++; for (int i = 1; i < m; i++) ws[i] += ws[i - 1]; for (int i = n - 1; i >= 0; i--) b[--ws[wv[i]]] = a[i]; } void dc3(int *r, int *sa, int n, int m) { int i, j, *rn = r + n, *san = sa + n, ta = 0, tb = (n + 1) / 3, tbc = 0, p; r[n] = r[n + 1] = 0; for (i = 0; i < n; i++) if (i % 3 != 0) wa[tbc++] = i; Rsort(r + 2, wa, wb, tbc, m); Rsort(r + 1, wb, wa, tbc, m); Rsort(r, wa, wb, tbc, m); for (p = 1, rn[F(wb[0])] = 0, i = 1; i < tbc; i++) rn[F(wb[i])] = c0(r, wb[i - 1], wb[i]) ? p - 1 : p++; if (p < tbc) dc3(rn, san, tbc, p); else for (i = 0; i < tbc; i++) san[rn[i]] = i; for (i = 0; i < tbc; i++) if (san[i] < tb) wb[ta++] = san[i] * 3; if (n % 3 == 1) wb[ta++] = n - 1; Rsort(r, wb, wa, ta, m); for (i = 0; i < tbc; i++) wv[wb[i] = G(san[i])] = i; for (i = 0, j = 0, p = 0; i < ta && j < tbc; p++) sa[p] = c12(wb[j] % 3, r, wa[i], wb[j]) ? wa[i++] : wb[j++]; for (; i < ta; p++) sa[p] = wa[i++]; for (; j < tbc; p++) sa[p] = wb[j++]; } void calheight(int *r, int *sa, int n) { int i, j, k = 0; for (i = 1; i <= n; i++) rak[sa[i]] = i; for (i = 0; i < n; height[rak[i++]] = k) for (k ? k-- : 0, j = sa[rak[i] - 1]; r[i + k] == r[j + k]; k++); for(int i=n;i;i--) rak[i]=rak[i-1]; for(int i=n;i;i--) sa[i]++; } int main() { while (scanf("%s", s+1)&&s[1] != '#') { n = strlen(s+1); for (int i = 1; i <= n; i++) cal[i] = s[i] - 'a' + 1; cal[n+1] = 0; dc3(cal+1, sa, n + 1, 30); calheight(cal+1, sa, n); for(int i=1;i<=n;i++) { printf("%d ",height[i]); }puts(""); } return 0; }
|