1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
| #include "sequence.h" #include <algorithm> #include <cstdio> #include <cstring> #include <iostream> #include <vector>
using pii = std::pair<int, int>;
const int kMaxN = 5e5 + 5;
struct Node { int mxx, mxy, mix, miy;
Node() {} Node(int _mxx, int _mxy, int _mix, int _miy) : mxx(_mxx), mxy(_mxy), mix(_mix), miy(_miy) {} };
struct LYX { pii p; int op, id;
LYX() {} LYX(pii _p, int _op, int _id) : p(_p), op(_op), id(_id) {} };
int n; int a[kMaxN], mxx[kMaxN << 2], mxy[kMaxN << 2], mix[kMaxN << 2], miy[kMaxN << 2], tagx[kMaxN << 2], tagy[kMaxN << 2]; int tr[kMaxN << 2]; std::vector<int> pos[kMaxN]; LYX pp[kMaxN << 1];
bool cmp(const LYX &l1, const LYX &l2) { return l1.p.first < l2.p.first; }
Node merge(Node ls, Node rs) { return Node(std::max(ls.mxx, rs.mxx), std::max(ls.mxy, rs.mxy), std::min(ls.mix, rs.mix), std::min(ls.miy, rs.miy)); }
void pushup(int x) { mxx[x] = std::max(mxx[x << 1], mxx[x << 1 | 1]); mix[x] = std::min(mix[x << 1], mix[x << 1 | 1]); mxy[x] = std::max(mxy[x << 1], mxy[x << 1 | 1]); miy[x] = std::min(miy[x << 1], miy[x << 1 | 1]); }
void addtagx(int x, int v) { mxx[x] += v, mix[x] += v, tagx[x] += v; }
void addtagy(int x, int v) { mxy[x] += v, miy[x] += v, tagy[x] += v; }
void pushdown(int x) { if (!tagx[x] && !tagy[x]) return; if (tagx[x]) addtagx(x << 1, tagx[x]), addtagx(x << 1 | 1, tagx[x]); if (tagy[x]) addtagy(x << 1, tagy[x]), addtagy(x << 1 | 1, tagy[x]); tagx[x] = tagy[x] = 0; }
void update(int x, int l, int r, int ql, int qr, int vx, int vy) { if (l > qr || r < ql) { return; } else if (l >= ql && r <= qr) { return addtagx(x, vx), addtagy(x, vy); } pushdown(x); int mid = (l + r) >> 1; update(x << 1, l, mid, ql, qr, vx, vy), update(x << 1 | 1, mid + 1, r, ql, qr, vx, vy); pushup(x); }
Node query(int x, int l, int r, int ql, int qr) { if (l > qr || r < ql) { return Node(-1e9, -1e9, 1e9, 1e9); } else if (l >= ql && r <= qr) { return Node(mxx[x], mxy[x], mix[x], miy[x]); } pushdown(x); int mid = (l + r) >> 1; Node ls = query(x << 1, l, mid, ql, qr), rs = query(x << 1 | 1, mid + 1, r, ql, qr); return merge(ls, rs); }
void upd(int x, int v) { for (; x <= 2e6; x += x & -x) tr[x] = std::min(tr[x], v); }
int qry(int x) { int ret = 1e9; for (; x; x -= x & -x) ret = std::min(ret, tr[x]); return ret; }
void clr(int x) { for (; x <= 2e6; x += x & -x) tr[x] = 1e9; }
int solve(int val = 1) { for (int i = 1; i <= n; ++i) update(1, 0, n, i, n, 1, -1); int ret = 0; memset(tr, 0x3f, sizeof(tr)); for (int i = 1; i <= n; ++i) { for (auto x : pos[i]) if (x && x <= n) update(1, 0, n, x, n, 0, 2); int cnt = 0; for (int j = 0; j + 1 < static_cast<int>(pos[i].size()); ++j) { auto p = query(1, 0, n, pos[i][j], pos[i][j + 1] - 1); pp[++cnt] = LYX(std::make_pair(p.mix, p.miy), 0, j); pp[++cnt] = LYX(std::make_pair(p.mxx, p.mxy), 1, j); } std::sort(pp + 1, pp + 1 + cnt, cmp); int now = 0; for (int j = 1, k; j <= cnt; j = k) { now = j; for (k = j; k <= cnt && pp[k].p.first == pp[j].p.first; ++k) if (pp[k].op == 0) upd(pp[k].p.second + 1e6, pp[k].id); for (int s = j; s < k; ++s) if (pp[s].op == 1) ret = std::max(ret, pp[s].id - qry(pp[s].p.second + 1e6)); } for (int k = 1; k < now; ++k) clr(pp[k].p.second + 1e6); for (auto x : pos[i]) if (x && x <= n) update(1, 0, n, x, n, -2, 0); } return ret; }
int sequence(int N, std::vector<int> A) { n = N; for (int i = 0; i < n; ++i) a[i + 1] = A[i]; for (int i = 1; i <= n; ++i) pos[i].emplace_back(0); for (int i = 1; i <= n; ++i) pos[a[i]].emplace_back(i); for (int i = 1; i <= n; ++i) pos[i].emplace_back(n + 1); return solve(); }
|