orz JT真是太神辣
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<iostream> 6 7 using namespace std; 8 9 void setIO(const string& s) { 10 freopen((s + ".in").c_str(), "r", stdin); 11 freopen((s + ".out").c_str(), "w", stdout); 12 } 13 template<typename Q> Q read(Q& x) { 14 static char c, f; 15 for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1; 16 for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0'; 17 if(f) x = -x; 18 return x; 19 } 20 template<typename Q> Q read() { 21 static Q x; read(x); return x; 22 } 23 24 25 const int N = 3000 + 10; 26 27 char s[N]; 28 int sa[N], n; 29 void build_sa(int m) { 30 static int t1[N * 2], t2[N * 2], c[N]; 31 int *x = t1, *y = t2; 32 for(int i = 0; i < m; i++) c[i] = 0; 33 for(int i = 0; i < n; i++) c[x[i] = s[i]]++; 34 for(int i = 1; i < m; i++) c[i] += c[i-1]; 35 for(int i = 0; i < n; i++) sa[--c[x[i]]] = i; 36 37 for(int k = 1; k < n; k <<= 1) { 38 int p = 0; 39 for(int i = n - 1; i >= n - k; i--) y[p++] = i; 40 for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k; 41 for(int i = 0; i < m; i++) c[i] = 0; 42 for(int i = 0; i < n; i++) c[x[i]]++; 43 for(int i = 1; i < m; i++) c[i] += c[i-1]; 44 for(int i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; 45 46 p = 1, swap(x, y), x[sa[0]] = 0; 47 for(int i = 1; i < n; i++) { 48 x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k]) ? p - 1 : p++; 49 } 50 if(p >= n) break; 51 m = p; 52 } 53 } 54 55 int rank[N], height[N]; 56 57 void build_height() { 58 for(int i = 0; i < n; i++) rank[sa[i]] = i; 59 for(int k = 0, i = 0; i < n; i++) { 60 if(k) k--; 61 if(!rank[i]) continue; 62 int j = sa[rank[i]-1]; 63 while(s[i+k] == s[j+k]) k++; 64 height[rank[i]] = k; 65 } 66 } 67 68 int main() { 69 #ifdef DEBUG 70 freopen("in.txt", "r", stdin); 71 freopen("out.txt", "w", stdout); 72 #endif 73 74 75 scanf("%d%s", &n, s); 76 build_sa(256); 77 build_height(); 78 79 for(int R, L = 1; L < n; L++) { 80 for(int h = height[L-1] + 1; h <= height[L]; h++) { 81 for(R = L + 1; height[R] >= h; R++); 82 printf("%d\n", R - L + 1); 83 } 84 } 85 86 return 0; 87 }