1 FZU 2267 The Bigger the Better
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <stack> 9 #include <map> 10 #include <set> 11 #include <cmath> 12 #include <cctype> 13 #include <ctime> 14 15 using namespace std; 16 17 #define REP(i, n) for (int i = 0; i < (n); ++i) 18 #define eps 1e-9 19 #define rank rank_t 20 21 typedef long long ll; 22 typedef pair<int, int> pii; 23 24 const int INF = 0x7fffffff; 25 const int maxn = 2e5 + 10; 26 int sa[maxn], cnt[maxn], t1[maxn], t2[maxn], rank[maxn], height[maxn]; 27 int a[maxn / 2], b[maxn / 2], s[maxn], ans[maxn], Min[maxn][20], key[maxn]; 28 29 void build_sa(int Max, int len_t) { 30 int i, p, *x = t1, *y = t2; 31 for (i = 0; i < Max; ++i) { cnt[i] = 0; } 32 for (i = 0; i < len_t; ++i) { ++cnt[x[i] = s[i]]; } 33 for (i = 1; i < Max; ++i) { cnt[i] += cnt[i - 1]; } 34 for (i = len_t - 1; i >= 0; --i) { sa[--cnt[x[i]]] = i; } 35 for (int k = 1; k <= len_t; k <<= 1) { 36 p = 0; 37 for (i = len_t - k; i < len_t; ++i) { y[p++] = i; } 38 for (i = 0; i < len_t; ++i) { 39 if (sa[i] >= k) { y[p++] = sa[i] - k; } 40 } 41 for (i = 0; i < Max; ++i) { cnt[i] = 0; } 42 for (i = 0; i < len_t; ++i) { ++cnt[x[y[i]]]; } 43 for (i = 1; i < Max; ++i) { cnt[i] += cnt[i - 1]; } 44 for (i = len_t - 1; i >= 0; --i) { sa[--cnt[x[y[i]]]] = y[i]; } 45 swap(x, y); p = 1; x[sa[0]] = 0; 46 for (i = 1; i < len_t; ++i) { 47 if (y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k]) { 48 x[sa[i]] = p - 1; 49 } else { x[sa[i]] = p++; } 50 } 51 if (p >= len_t) { break; } Max = p; 52 } 53 } 54 void get_height(int len) { 55 int i, j, k = 0; 56 for (i = 0; i <= len; ++i) { rank[sa[i]] = i; } 57 for (i = 0; i < len; ++i) { 58 if (k) { --k; } j = sa[rank[i] - 1]; 59 while (s[i + k] == s[j + k]) { ++k; } 60 height[rank[i]] = k; 61 } 62 } 63 void init(int n) { 64 for (int i = 1; i <= n; ++i) { Min[i][0] = height[i]; } 65 for (int j = 1; (1 << j) <= n; ++j) { 66 for (int i = 1; i + (1 << j) - 1 <= n; ++i) { 67 Min[i][j] = min(Min[i][j - 1], Min[i + (1 << (j - 1))][j - 1]); 68 } 69 } 70 } 71 inline int rmq(int l, int r) { 72 int k = key[r - l + 1]; 73 return min(Min[l][k], Min[r - (1 << k) + 1][k]); 74 } 75 void print(int l, int len) { 76 for (int i = l; i < len; ++i) { printf("%d ", s[i]); } printf("\n"); 77 } 78 79 int main() { 80 #ifdef __AiR_H 81 freopen("in.txt", "r", stdin); 82 // freopen("out.txt", "w", stdout); 83 #endif // __AiR_H 84 int T, n, m, Case = 0, len, ans_cnt; 85 for (int i = 1; i < maxn; ++i) { 86 while ((1 << (key[i] + 1)) <= i) { ++key[i]; } 87 } 88 scanf("%d", &T); 89 while (T--) { 90 scanf("%d %d", &n, &m); len = ans_cnt = 0; 91 for (int i = 0; i < n; ++i) { scanf("%d", &a[i]); s[len++] = a[i]; } 92 s[len++] = 10; 93 for (int i = 0; i < m; ++i) { scanf("%d", &b[i]); s[len++] = b[i]; } 94 s[len] = 0; build_sa(11, len + 1); get_height(len); init(len); 95 int t_1, t_2, t_3; 96 for (int i = 0, j = 0; ; ) { 97 if (i == n) { 98 for (; j < m; ++j) { ans[ans_cnt++] = b[j]; } break; 99 } 100 if (j == m) { 101 for (; i < n; ++i) { ans[ans_cnt++] = a[i]; } break; 102 } 103 if (a[i] > b[j]) { ans[ans_cnt++] = a[i]; ++i; continue; } 104 if (b[j] > a[i]) { ans[ans_cnt++] = b[j]; ++j; continue; } 105 t_1 = rank[i]; t_2 = rank[n + j + 1]; 106 if (t_1 > t_2) { swap(t_1, t_2); } t_3 = rmq(t_1 + 1, t_2); 107 if (i + t_3 >= n) { ans[ans_cnt++] = b[j]; ++j; continue; } 108 if (j + t_3 >= m) { ans[ans_cnt++] = a[i]; ++i; continue; } 109 if (a[i + t_3] > b[j + t_3]) { ans[ans_cnt++] = a[i]; ++i; continue; } 110 ans[ans_cnt++] = b[j]; ++j; 111 } 112 printf("Case %d: ", ++Case); 113 for (int i = 0; i < ans_cnt; ++i) { printf("%d", ans[i]); } 114 printf("\n"); 115 } 116 #ifdef __AiR_H 117 printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC); 118 #endif // __AiR_H 119 return 0; 120 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <stack> 9 #include <map> 10 #include <set> 11 #include <cmath> 12 #include <cctype> 13 #include <ctime> 14 15 using namespace std; 16 17 #define REP(i, n) for (int i = 0; i < (n); ++i) 18 #define eps 1e-9 19 #define rank rank_t 20 21 typedef long long ll; 22 typedef pair<int, int> pii; 23 24 const int INF = 0x7fffffff; 25 const int maxn = 1e5 + 10; 26 int T, len, Case = 0, Size; 27 char key[2], s[maxn]; 28 int sum[maxn]; 29 int sa[maxn], cnt[maxn], t1[maxn], t2[maxn], rank[maxn], height[maxn]; 30 vector<int> v; 31 32 void build_sa(int m) { 33 int i, p, *x = t1, *y = t2, len_t = len + 1; 34 for (i = 0; i < m; ++i) { cnt[i] = 0; } 35 for (i = 0; i < len_t; ++i) { ++cnt[x[i] = s[i]]; } 36 for (i = 1; i < m; ++i) { cnt[i] += cnt[i - 1]; } 37 for (i = len_t - 1; i >= 0; --i) { sa[--cnt[x[i]]] = i; } 38 for (int k = 1; k <= len_t; k <<= 1) { 39 p = 0; 40 for (i = len_t - k; i < len_t; ++i) { y[p++] = i; } 41 for (i = 0; i < len_t; ++i) { 42 if (sa[i] >= k) { y[p++] = sa[i] - k; } 43 } 44 for (i = 0; i < m; ++i) { cnt[i] = 0; } 45 for (i = 0; i < len_t; ++i) { ++cnt[x[y[i]]]; } 46 for (i = 0; i < m; ++i) { cnt[i] += cnt[i - 1]; } 47 for (i = len_t - 1; i >= 0; --i) { sa[--cnt[x[y[i]]]] = y[i]; } 48 swap(x, y); p = 1; x[sa[0]] = 0; 49 for (i = 1; i < len_t; ++i) { 50 if (y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k]) { 51 x[sa[i]] = p - 1; 52 } else { x[sa[i]] = p++; } 53 } 54 if (p >= len_t) { break; } m = p; 55 } 56 } 57 void get_height() { 58 int i, j, k = 0; 59 for (int i = 0; i <= len; ++i) { rank[sa[i]] = i; } 60 for (int i = 0; i < len; ++i) { 61 if (k) { --k; } j = sa[rank[i] - 1]; 62 while (s[i + k] == s[j + k]) { ++k; } 63 height[rank[i]] = k; 64 } 65 } 66 void print(int l) { 67 for (int i = l; i < len; ++i) { printf("%c", s[i]); } printf("\n"); 68 } 69 inline bool check(int l, int r) { return sum[r + 1] - sum[l] > 0; } 70 int cal(int x) { 71 int t = lower_bound(v.begin(), v.end(), x) - v.begin(); 72 if (t == Size) { return len; } return v[t]; 73 } 74 75 int main() { 76 #ifdef __AiR_H 77 freopen("in.txt", "r", stdin); 78 // freopen("out.txt", "w", stdout); 79 #endif // __AiR_H 80 scanf("%d", &T); 81 while (T--) { 82 scanf("%s %s", key, s); len = strlen(s); s[len] = 0; 83 memset(sum, 0, sizeof(sum)); v.clear(); 84 for (int i = 0; i < len; ++i) { 85 if (s[i] == key[0]) { v.push_back(i); sum[i + 1] = 1; } 86 } 87 Size = v.size(); 88 for (int i = 1; i <= len; ++i) { sum[i] += sum[i - 1]; } 89 build_sa('z' + 1); get_height(); 90 // for (int i = 1; i <= len; ++i) { print(sa[i]); } 91 // for (int i = 1; i <= len; ++i) { printf("%d ", height[i]); } printf("\n"); 92 ll ans = 0, t; 93 for (int i = 1; i <= len; ++i) { 94 t = len - sa[i] - height[i]; 95 if (check(sa[i], sa[i] + height[i] - 1)) { ans += t; } 96 else { 97 ans += len - cal(sa[i] + height[i]); 98 } 99 } 100 printf("Case #%d: %I64d\n", ++Case, ans); 101 } 102 #ifdef __AiR_H 103 printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC); 104 #endif // __AiR_H 105 return 0; 106 }