Advertisement
Guest User

F

a guest
Mar 31st, 2020
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.60 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <set>
  4. #include <unordered_map>
  5. #include <algorithm>
  6. #include <string>
  7. #include <unordered_set>
  8. #include <list>
  9. #include <map>
  10. #include <queue>
  11.  
  12. #define mp make_pair
  13. #define i64 long long;
  14. #define ui64 unsigned long long;
  15. using namespace std;
  16.  
  17. string s;
  18. int n;
  19.  
  20. vector<int> c;
  21. vector<int> v;
  22. vector<int> colors;
  23.  
  24. bool cmp(int a, int b) {
  25. return s[a] < s[b];
  26. }
  27.  
  28. int length = 1;
  29. bool cmp1(int a, int b) {
  30. if (c[a] != c[b]) {
  31. return c[a] < c[b];
  32. }
  33. return c[(a + length) % n] < c[(b + length) % n];
  34. }
  35.  
  36.  
  37. struct SegmentTree {
  38. SegmentTree(int n) {
  39. v.resize(4 * n + 1, inf);
  40. }
  41. void set(int u, int L, int R, int pos, int val) {
  42. if (L > pos || R < pos) return;
  43. if (L == R && pos == L) {
  44. v[u] = val;
  45. return;
  46. }
  47. int m = (L + R) / 2;
  48. set(u * 2, L, m, pos, val);
  49. set(u * 2 + 1, m + 1, R, pos, val);
  50. v[u] = min(v[u * 2], v[u * 2 + 1]);
  51. }
  52.  
  53. int get(int u, int L, int R, int l, int r) {
  54. if (L > r || R < l) return inf;
  55. if (L >= l && R <= r) {
  56. return v[u];
  57. }
  58. int m = (L + R) / 2;
  59. return min(get(u * 2, L, m, l, r), get(u * 2 + 1, m + 1, R, l, r));
  60. }
  61. int inf = 1e9 + 10;
  62. vector<int> v;
  63. };
  64.  
  65.  
  66. int get_color_suff(int suf) {
  67. for (int i = 0; i < colors.size(); ++i) {
  68. if (suf <= colors[i]) {
  69. return i;
  70. }
  71. }
  72. exit(-1);
  73. }
  74. int main() {
  75. #ifdef _KOCH
  76. freopen("input.txt", "r", stdin);
  77. #else
  78. // freopen("common.in", "r", stdin);
  79. // freopen("common.out", "w", stdout);
  80. #endif
  81. int symb = 33;
  82. int k;
  83. cin >> k;
  84. colors.resize(k);
  85. for (int i = 0; i < k; ++i) {
  86. string a;
  87. cin >> a;
  88. s += a;
  89. colors[i] = s.size();
  90. s += char(symb + i);
  91. }
  92. if (k == 1) {
  93. s.pop_back();
  94. cout << s << endl;
  95. return 0;
  96. }
  97. v.resize(s.size());
  98. c.resize(s.size());
  99. n = s.size();
  100. for (int i = 0; i < v.size(); ++i) {
  101. v[i] = i;
  102. }
  103. stable_sort(v.begin(), v.end(), cmp);
  104. int kek = 0;
  105. c[v[0]] = 0;
  106. for (int i = 1; i < v.size(); ++i) {
  107. if (s[v[i]] == s[v[i - 1]]) {
  108. c[v[i]] = kek;
  109. }
  110. else {
  111. kek++;
  112. c[v[i]] = kek;
  113. }
  114. }
  115.  
  116.  
  117. for (; length <= v.size(); length *= 2) {
  118. stable_sort(v.begin(), v.end(), cmp1);
  119. kek = 0;
  120. vector<int> tmp(n);
  121. tmp[v[0]] = 0;
  122. for (int i = 1; i < v.size(); ++i) {
  123. if (cmp1(v[i], v[i - 1]) == cmp1(v[i - 1], v[i])) {
  124. tmp[v[i]] = kek;
  125. }
  126. else {
  127. kek++;
  128. tmp[v[i]] = kek;
  129. }
  130. }
  131. swap(c, tmp);
  132. }
  133.  
  134.  
  135. std::vector<int> rev(n);
  136. vector<int> lcp(n);
  137. for (int i = 0; i < n; ++i) {
  138. rev[v[i]] = i;
  139. }
  140.  
  141. for (int i = 0, k = 0; i < n; ++i)
  142. {
  143. if (k > 0) {
  144. k--;
  145. }
  146. if (rev[i] == n - 1)
  147. {
  148. k = 0;
  149. continue;
  150. }
  151.  
  152. int j = v[rev[i] + 1];
  153. while (max(i + k, j + k) < n && s[i + k] == s[j + k]) {
  154. k++;
  155. }
  156.  
  157. lcp[rev[i]] = k;
  158. }
  159.  
  160. lcp.insert(lcp.begin(), 0);
  161.  
  162.  
  163. SegmentTree st(lcp.size());
  164.  
  165. for (int i = 0; i < lcp.size(); ++i) {
  166. st.set(1, 0, lcp.size() - 1, i, lcp[i]);
  167. }
  168.  
  169. map<int, int> segment_colors;
  170.  
  171.  
  172. int l = 0;
  173. int r = 0;
  174. int res = 0;
  175. int x = 0;
  176. segment_colors[get_color_suff(v[0])]++;
  177.  
  178. while (r != lcp.size()) {
  179. while (segment_colors.size() != k) {
  180. r++;
  181. if (r >= v.size()) {
  182. break;
  183. }
  184. segment_colors[get_color_suff(v[r])]++;
  185. }
  186. while (segment_colors.size() >= k) {
  187. int ans = st.get(1, 0, lcp.size() - 1, l + 1, r);
  188. if (res < ans) {
  189. x = v[l+1];
  190. res = ans;
  191. }
  192. auto it = segment_colors.find(get_color_suff(v[l]));
  193. it->second--;
  194. if (it->second == 0) {
  195. segment_colors.erase(it);
  196. }
  197. l++;
  198. }
  199. }
  200. for (int i = 0; i < res; ++i) {
  201. cout << s[x + i];
  202. }
  203. cout << endl;
  204. return 0;
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement