Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define int long long
- const int N = 200005;
- const int loga = 21;
- int dp[loga][N];
- int a[N];
- map <int, vector<int>> pos;
- int deg[loga];
- int _lg[N], ans, id, mnm;
- void pre_calc_log() {
- _lg[0] = _lg[1] = 0;
- for (int i = 2; i < N; ++i)
- _lg[i] = _lg[(i >> 1)] + 1;
- }
- void pre_calc_deg() {
- deg[0] = 1;
- for (int i = 1; i < loga; ++i)
- deg[i] = (deg[i - 1] << 1LL);
- }
- int get_ans(int l, int r) {
- int sz = r - l + 1;
- int k = _lg[sz];
- r += 1;
- return min(dp[k][l], dp[k][r - deg[k]]);
- }
- int solve(int l, int r) {
- if (l > r)
- return 0;
- if (l == r) {
- if (a[l] * 2 > ans) {
- ans = a[l] * 2;
- id = l;
- mnm = a[l];
- }
- return a[l] * 2;
- }
- auto mn = get_ans(l, r);
- int d = (r - l + 2) * mn;
- if (d > ans) {
- ans = d;
- id = l;
- mnm = mn;
- }
- int poss = *lower_bound(pos[mn].begin(), pos[mn].end(), l);
- d = max(d, solve(l, poss - 1));
- d = max(d, solve(poss + 1, r));
- return d;
- }
- void make(vector <int> &suf, vector <int> &cls, vector<int>& s) {
- vector <pair<char, int>> ord;
- for (int i = 0; i < s.size(); ++i) {
- ord.push_back(make_pair(s[i], i));
- }
- int cur = -1;
- char prev = '0';
- sort(ord.begin(), ord.end());
- int j = 0;
- for (auto i : ord) {
- suf[j++] = i.second;
- if (i.first != prev) {
- cur++;
- }
- cls[i.second] = cur;
- prev = i.first;
- }
- }
- vector <int> suffix_array(vector<int>& s) {
- s.push_back(-100);
- int n = s.size();
- vector <int> suf(n), cls(n);
- make(suf, cls, s);
- int l = 0;
- while ((1 << l) < n) {
- vector <int> nowsort;
- for (int i = 0; i < n; ++i) {
- int cur = suf[i];
- int id = (cur - (1 << l) + n) % n;
- nowsort.push_back(id);
- }
- vector <int> beg(n), cnt(n);
- for (int i = 0; i < n; ++i) {
- cnt[cls[i]]++;
- }
- for (int i = 1; i < n; ++i) {
- beg[i] += beg[i - 1] + cnt[i - 1];
- }
- for (int i = 0; i < n; ++i) {
- int f = cls[nowsort[i]];
- suf[beg[f]++] = nowsort[i];
- }
- pair <int, int> prev = {-1, -1};
- int cur = -1;
- vector <int> newcls(n);
- for (int i = 0; i < n; ++i) {
- int ct = suf[i];
- pair <int, int> F = {cls[ct], cls[(ct + (1 << l)) % n]};
- if (F != prev) {
- cur++;
- }
- newcls[suf[i]] = cur;
- prev = F;
- }
- cls = newcls;
- l++;
- }
- return suf;
- }
- vector <int> getLcp(vector <int> &suf, vector<int>& s) {
- int n = suf.size();
- vector <int> pos(n);
- for (int i = 0; i < suf.size(); ++i)
- pos[suf[i]] = i;
- vector <int> lcp(n);
- for (int i = 0; i < n; i++) {
- if (pos[i] == n - 1) continue;
- int z = 0;
- if (i > 0 && pos[i - 1] != n - 1 && lcp[pos[i - 1]] > 0)
- z = lcp[pos[i - 1]] - 1;
- while (i + z < n && suf[pos[i] + 1] + z < n && s[i + z] == s[suf[pos[i] + 1] + z]) z++;
- lcp[pos[i]] = z;
- }
- return lcp;
- }
- void solve() {
- pre_calc_deg();
- pre_calc_log();
- int n, m;
- cin >> n >> m;
- vector <int> b(n);
- for (int i = 0; i < n; ++i) {
- cin >> b[i];
- }
- set <int> k(b.begin(), b.end());
- if (k.size() == n) {
- cout << n << '\n' << n << '\n';
- for (int i : b)
- cout << i << ' ';
- exit(0);
- }
- auto suff = suffix_array(b);
- auto get = getLcp(suff, b);
- n = get.size();
- for (int i = 0; i < n; ++i) {
- a[i] = get[i];
- pos[a[i]].push_back(i);
- }
- for (int i = 1; i < n; ++i)
- dp[0][i] = a[i];
- for (int i = 1; i < loga; ++i) {
- for (int j = 1; j < n; ++j) {
- if (j + deg[i - 1] < n) {
- dp[i][j] = min(dp[i - 1][j], dp[i - 1][j + deg[i - 1]]);
- }
- }
- }
- int g = solve(1, n - 1);
- if (g > b.size() - 1) {
- cout << g << '\n';
- cout << mnm << '\n';
- for (int i = suff[id]; i < suff[id] + mnm; ++i) {
- cout << b[i] << ' ';
- }
- }
- else {
- cout << b.size() - 1<< '\n' << b.size() - 1 << '\n';
- b.pop_back();
- for (int i : b)
- cout << i << ' ';
- exit(0);
- }
- }
- signed main() {
- ios::sync_with_stdio(false);
- cin.tie(0);
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement