Advertisement
MathQ_

Untitled

May 5th, 2021
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.36 KB | None | 0 0
  1. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
  2. #pragma GCC optimize 03
  3. #pragma GCC optimize("unroll-loops")
  4.  
  5. #include <iostream>
  6. #include <iomanip>
  7. #include <algorithm>
  8. #include <iterator>
  9. #include <cmath>
  10. #include <ctime>
  11. #include <vector>
  12. #include <deque>
  13. #include <queue>
  14. #include <set>
  15. #include <map>
  16. #include <stack>
  17. #include <string>
  18. #include <random>
  19. #include <numeric>
  20. #include <unordered_set>
  21.  
  22. typedef std::pair<int, int> pii;
  23. typedef std::pair<char, short> psc;
  24. typedef std::pair<std::pair<char, short>, std::pair<char, short>> pss;
  25. typedef unsigned short ushort;
  26. typedef unsigned long long ull;
  27. typedef long long ll;
  28. typedef long double lb;
  29.  
  30. #define fast ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  31. #define file_in freopen("input.txt", "r", stdin);
  32. #define file_in_out freopen("swapper.in", "r", stdin); freopen("swapper.out", "w", stdout);
  33. #define all(x) (x).begin(), (x).end()
  34. #define fi first
  35. #define se second
  36.  
  37. using namespace std;
  38.  
  39. template<typename T>
  40. istream& operator>>(istream &in, vector<T> &v) {
  41.     for (auto &it : v) {
  42.         in >> it;
  43.     }
  44.     return in;
  45. }
  46.  
  47. template<typename T>
  48. ostream& operator<<(ostream &out, vector<T> &v) {
  49.     if (!v.empty()) {
  50.         out << v.front();
  51.         for (int i = 1; i < v.size(); ++i) {
  52.             out << " " << v[i];
  53.         }
  54.     }
  55.     return out;
  56. }
  57.  
  58. template<typename T1, typename T2>
  59. ostream& operator<<(ostream &out, pair<T1, T2> &v) {
  60.     out << v.fi << " " << v.se;
  61.     return out;
  62. }
  63.  
  64. const psc inf = {INT16_MAX, 5};
  65.  
  66. psc convert_to_psc(int n) {
  67.     return {n / INT16_MAX, n % INT16_MAX};
  68. }
  69.  
  70. int convert_to_int(psc n) {
  71.     return n.fi * INT16_MAX + n.se;
  72. }
  73.  
  74. bool check_less(psc &p1, psc &p2) {
  75.     return convert_to_int(p1) < convert_to_int(p2);
  76. }
  77.  
  78. psc Min(psc &p1, psc &p2) {
  79.     return (convert_to_int(p1) < convert_to_int(p2) ? p1 : p2);
  80. }
  81.  
  82. psc Max(psc &p1, psc &p2) {
  83.     return (convert_to_int(p1) > convert_to_int(p2) ? p1 : p2);
  84. }
  85.  
  86. ostream& operator<<(ostream &out, psc &v) {
  87.     out << convert_to_int(v);
  88.     return out;
  89. }
  90.  
  91. int bin_search(vector<psc> &v, psc x) {
  92.     int l = -1, r = v.size();
  93.     while (r - l > 1) {
  94.         int m = r + l >> 1;
  95.         if (check_less(v[m], x)) {
  96.             l = m;
  97.         } else {
  98.             r = m;
  99.         }
  100.     }
  101.     return r;
  102. }
  103.  
  104. struct sparse_table {
  105.     vector<vector<pss>> sp;
  106.     sparse_table() {}
  107.     sparse_table(vector<psc> a) {
  108.         int n = a.size();
  109.         int LOG = __lg(n) + 1;
  110.         sp.resize(n, vector<pss>(LOG, {inf, inf}));
  111.         for (int i = 0; i < n; ++i) sp[i][0] = {a[i], convert_to_psc(-convert_to_int(a[i]))};
  112.         for (int j = 1; j < LOG; ++j) {
  113.             for (int i = 0; i + (1 << j) <= n; ++i) {
  114.                 sp[i][j] = {Min(sp[i][j - 1].fi, sp[i + (1 << (j - 1))][j - 1].fi),
  115.                             Min(sp[i][j - 1].se, sp[i + (1 << (j - 1))][j - 1].se)};
  116.             }
  117.         }
  118.     }
  119.  
  120.     psc get_min(int l, int r) {
  121.         int j = __lg(r - l + 1);
  122.         return Min(sp[l][j].fi, sp[r - (1 << j) + 1][j].fi);
  123.     }
  124.  
  125.     psc get_max(int l, int r) {
  126.         int j = __lg(r - l + 1);
  127.         return Min(sp[l][j].se, sp[r - (1 << j) + 1][j].se);
  128.     }
  129. };
  130.  
  131. const int N = 524287;
  132. vector<int> lcp;
  133. pair<vector<psc>, sparse_table> t[N];
  134.  
  135. void build(int id, int l, int r) {
  136.     if (l + 1 == r) { t[id].fi = {convert_to_psc(lcp[l])}; t[id].se = sparse_table({convert_to_psc(l)}); return; }
  137.     build(id * 2 + 1, l, l + r >> 1);
  138.     build(id * 2 + 2, l + r >> 1, r);
  139.     vector<pss> new_v, v1, v2;
  140.     for (int i = 0; i < t[id * 2 + 1].fi.size(); ++i) v1.push_back({t[id * 2 + 1].fi[i], t[id * 2 + 1].se.sp[i][0].fi});
  141.     for (int i = 0; i < t[id * 2 + 2].fi.size(); ++i) v2.push_back({t[id * 2 + 2].fi[i], t[id * 2 + 2].se.sp[i][0].fi});
  142.     merge(all(v1), all(v2), back_inserter(new_v));
  143.     vector<psc> nums, idxs;
  144.     for (auto el : new_v) { nums.push_back(el.fi); idxs.push_back(el.se); }
  145.     t[id].fi = nums;
  146.     t[id].se = sparse_table(idxs);
  147. }
  148.  
  149. psc get_left(int id, int l, int r, int i) {
  150.     if (l >= i) { return convert_to_psc(-1); }
  151.     if (r <= i) {
  152.         int last = bin_search(t[id].fi, convert_to_psc(lcp[i])) - 1;
  153.         return (last == -1 ? convert_to_psc(-1) : convert_to_psc(-convert_to_int(t[id].se.get_max(0, last))));
  154.     }
  155.     psc left  = get_left(id * 2 + 1, l, l + r >> 1, i);
  156.     psc right = get_left(id * 2 + 2, l + r >> 1, r, i);
  157.     return Max(left, right);
  158. }
  159.  
  160. psc get_right(int id, int l, int r, int i) {
  161.     if (r <= i) { return convert_to_psc(N); }
  162.     if (l >= i) {
  163.         int last = bin_search(t[id].fi, convert_to_psc(lcp[i])) - 1;
  164.         return (last == -1 ? convert_to_psc(N) : t[id].se.get_min(0, last));
  165.     }
  166.     psc left  = get_right(id * 2 + 1, l, l + r >> 1, i);
  167.     psc right = get_right(id * 2 + 2, l + r >> 1, r, i);
  168.     return Min(left, right);
  169. }
  170.  
  171. void count_sort(vector<int> &p, vector<int> &c) {
  172.     int n = p.size();
  173.     vector<int> pos(n + 1), p_new(n);
  174.     for (auto x : c) {
  175.         pos[x + 1]++;
  176.     }
  177.     for (int i = 1; i < n; ++i) pos[i] += pos[i - 1];
  178.     for (auto x : p) {
  179.         int i = c[x];
  180.         p_new[pos[i]] = x;
  181.         pos[i]++;
  182.     }
  183.     p = p_new;
  184. }
  185.  
  186. void build(string &s, vector<int> &p, vector<int> &c) {
  187.     int n = p.size();
  188.     vector<pair<char, int>> a(n);
  189.     for (int i = 0; i < n; ++i) a[i] = {s[i], i};
  190.     sort(all(a));
  191.     for (int i = 0; i < n; ++i) p[i] = a[i].se;
  192.     for (int i = 1; i < n; ++i) {
  193.         c[p[i]] = c[p[i - 1]];
  194.         if (a[i].fi != a[i - 1].fi) ++c[p[i]];
  195.     }
  196.  
  197.     int k = 0;
  198.     while ((1 << k) < n) {
  199.         for (int i = 0; i < n; ++i) {
  200.             p[i] = (p[i] - (1 << k) + n) % n;
  201.         }
  202.         count_sort(p, c);
  203.         vector<int> c_new(n);
  204.         for (int i = 1; i < n; ++i) {
  205.             pii prev = {c[p[i - 1]], c[(p[i - 1] + (1 << k)) % n]};
  206.             pii now = {c[p[i]], c[(p[i] + (1 << k)) % n]};
  207.             c_new[p[i]] = c_new[p[i - 1]];
  208.             if (prev != now) ++c_new[p[i]];
  209.         }
  210.         c = c_new;
  211.         ++k;
  212.     }
  213. }
  214.  
  215. void build_lcp(string &s, vector<int> &p, vector<int> &c) {
  216.     int n = p.size();
  217.     int cur_lcp = 0;
  218.     for (int i = 0; i < n - 1; ++i) {
  219.         int j = p[c[i] - 1];
  220.         while (s[i + cur_lcp] == s[j + cur_lcp]) cur_lcp++;
  221.         lcp[c[i]] = cur_lcp;
  222.         cur_lcp = max(cur_lcp - 1, 0);
  223.     }
  224. }
  225.  
  226. int main() {
  227.     fast
  228.     // file_in
  229.     // file_in_out
  230.     int n, m;
  231.     cin >> n >> m;
  232.     vector<short> v_string(n);
  233.     cin >> v_string;
  234.     string s;
  235.     for (auto el : v_string) s += el + '0';
  236.     s += "$"; ++n;
  237.     vector<int> p(n), c(n); lcp.resize(n);
  238.     build(s, p, c); build_lcp(s, p, c);
  239.     ll ans = 0;
  240.     string ref;
  241.  
  242.     build(0, 0, n);
  243.     for (int i = 0; i < n; ++i) {  
  244.         int left = convert_to_int(get_left(0, 0, n, i));
  245.         int right = min(n, convert_to_int(get_right(0, 0, n, i)));
  246.         if (ans < 1ll * lcp[i] * (right - left)) {
  247.             ans = 1ll * lcp[i] * (right - left);
  248.             ref = s.substr(p[i], lcp[i]);
  249.         }
  250.     }
  251.     if (ans < s.size() - 1) {
  252.         ans = s.size() - 1;
  253.         ref = s; ref.pop_back();
  254.     }
  255.     cout << ans << '\n';
  256.     cout << ref.size() << '\n';
  257.     for (auto el : ref) {
  258.         if (el == ':') {
  259.             cout << 10 << " ";
  260.         } else {
  261.             cout << el << " ";
  262.         }
  263.     }
  264.     return 0;
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement