Advertisement
cincout

Рефрен

Mar 14th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.58 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4.  
  5. const int N = 200005;
  6. const int loga = 21;
  7.  
  8. int dp[loga][N];
  9. int a[N];
  10. map <int, vector<int>> pos;
  11. int deg[loga];
  12. int _lg[N], ans, id, mnm;
  13.  
  14. void pre_calc_log() {
  15. _lg[0] = _lg[1] = 0;
  16. for (int i = 2; i < N; ++i)
  17. _lg[i] = _lg[(i >> 1)] + 1;
  18. }
  19.  
  20. void pre_calc_deg() {
  21. deg[0] = 1;
  22. for (int i = 1; i < loga; ++i)
  23. deg[i] = (deg[i - 1] << 1LL);
  24. }
  25.  
  26. int get_ans(int l, int r) {
  27. int sz = r - l + 1;
  28. int k = _lg[sz];
  29. r += 1;
  30. return min(dp[k][l], dp[k][r - deg[k]]);
  31. }
  32.  
  33. int solve(int l, int r) {
  34. if (l > r)
  35. return 0;
  36. if (l == r) {
  37. if (a[l] * 2 > ans) {
  38. ans = a[l] * 2;
  39. id = l;
  40. mnm = a[l];
  41. }
  42. return a[l] * 2;
  43. }
  44. auto mn = get_ans(l, r);
  45. int d = (r - l + 2) * mn;
  46. if (d > ans) {
  47. ans = d;
  48. id = l;
  49. mnm = mn;
  50. }
  51. int poss = *lower_bound(pos[mn].begin(), pos[mn].end(), l);
  52. d = max(d, solve(l, poss - 1));
  53. d = max(d, solve(poss + 1, r));
  54. return d;
  55. }
  56.  
  57. void make(vector <int> &suf, vector <int> &cls, vector<int>& s) {
  58. vector <pair<char, int>> ord;
  59. for (int i = 0; i < s.size(); ++i) {
  60. ord.push_back(make_pair(s[i], i));
  61. }
  62. int cur = -1;
  63. char prev = '0';
  64. sort(ord.begin(), ord.end());
  65. int j = 0;
  66. for (auto i : ord) {
  67. suf[j++] = i.second;
  68. if (i.first != prev) {
  69. cur++;
  70. }
  71. cls[i.second] = cur;
  72. prev = i.first;
  73. }
  74. }
  75.  
  76. vector <int> suffix_array(vector<int>& s) {
  77. s.push_back(-100);
  78. int n = s.size();
  79. vector <int> suf(n), cls(n);
  80. make(suf, cls, s);
  81. int l = 0;
  82. while ((1 << l) < n) {
  83. vector <int> nowsort;
  84. for (int i = 0; i < n; ++i) {
  85. int cur = suf[i];
  86. int id = (cur - (1 << l) + n) % n;
  87. nowsort.push_back(id);
  88. }
  89. vector <int> beg(n), cnt(n);
  90. for (int i = 0; i < n; ++i) {
  91. cnt[cls[i]]++;
  92. }
  93. for (int i = 1; i < n; ++i) {
  94. beg[i] += beg[i - 1] + cnt[i - 1];
  95. }
  96. for (int i = 0; i < n; ++i) {
  97. int f = cls[nowsort[i]];
  98. suf[beg[f]++] = nowsort[i];
  99. }
  100. pair <int, int> prev = {-1, -1};
  101. int cur = -1;
  102. vector <int> newcls(n);
  103. for (int i = 0; i < n; ++i) {
  104. int ct = suf[i];
  105. pair <int, int> F = {cls[ct], cls[(ct + (1 << l)) % n]};
  106. if (F != prev) {
  107. cur++;
  108. }
  109. newcls[suf[i]] = cur;
  110. prev = F;
  111. }
  112. cls = newcls;
  113. l++;
  114. }
  115. return suf;
  116. }
  117.  
  118. vector <int> getLcp(vector <int> &suf, vector<int>& s) {
  119. int n = suf.size();
  120. vector <int> pos(n);
  121. for (int i = 0; i < suf.size(); ++i)
  122. pos[suf[i]] = i;
  123. vector <int> lcp(n);
  124. for (int i = 0; i < n; i++) {
  125. if (pos[i] == n - 1) continue;
  126. int z = 0;
  127. if (i > 0 && pos[i - 1] != n - 1 && lcp[pos[i - 1]] > 0)
  128. z = lcp[pos[i - 1]] - 1;
  129. while (i + z < n && suf[pos[i] + 1] + z < n && s[i + z] == s[suf[pos[i] + 1] + z]) z++;
  130. lcp[pos[i]] = z;
  131. }
  132. return lcp;
  133. }
  134.  
  135. void solve() {
  136. pre_calc_deg();
  137. pre_calc_log();
  138. int n, m;
  139. cin >> n >> m;
  140. vector <int> b(n);
  141. for (int i = 0; i < n; ++i) {
  142. cin >> b[i];
  143. }
  144. set <int> k(b.begin(), b.end());
  145. if (k.size() == n) {
  146. cout << n << '\n' << n << '\n';
  147. for (int i : b)
  148. cout << i << ' ';
  149. exit(0);
  150. }
  151. auto suff = suffix_array(b);
  152. auto get = getLcp(suff, b);
  153. n = get.size();
  154. for (int i = 0; i < n; ++i) {
  155. a[i] = get[i];
  156. pos[a[i]].push_back(i);
  157. }
  158. for (int i = 1; i < n; ++i)
  159. dp[0][i] = a[i];
  160. for (int i = 1; i < loga; ++i) {
  161. for (int j = 1; j < n; ++j) {
  162. if (j + deg[i - 1] < n) {
  163. dp[i][j] = min(dp[i - 1][j], dp[i - 1][j + deg[i - 1]]);
  164. }
  165. }
  166. }
  167. int g = solve(1, n - 1);
  168. if (g > b.size() - 1) {
  169. cout << g << '\n';
  170. cout << mnm << '\n';
  171. for (int i = suff[id]; i < suff[id] + mnm; ++i) {
  172. cout << b[i] << ' ';
  173. }
  174. }
  175. else {
  176. cout << b.size() - 1<< '\n' << b.size() - 1 << '\n';
  177. b.pop_back();
  178. for (int i : b)
  179. cout << i << ' ';
  180. exit(0);
  181. }
  182. }
  183.  
  184. signed main() {
  185. ios::sync_with_stdio(false);
  186. cin.tie(0);
  187. solve();
  188. return 0;
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement