제출 #854460

#제출 시각아이디문제언어결과실행 시간메모리
854460dxz05서열 (APIO23_sequence)C++17
20 / 100
1832 ms76064 KiB
#include "sequence.h" #include <bits/stdc++.h> using namespace std; template <typename T> struct SegmentTree{ struct node{ T sum; T Min; T Max; T lazy; bool isUpdated; node(){ sum = Min = Max = 0; lazy = 0; isUpdated = false; }; node(T x){ sum = Min = Max = x; lazy = 0; isUpdated = false; } }; vector<node> tree; node neutral_element; inline void combine(node &par, node lf, node rg){ par.sum = lf.sum + rg.sum; par.Min = min(lf.Min, rg.Min); par.Max = max(lf.Max, rg.Max); } int _begin, _end; inline void init(int n){ _begin = 0; _end = n - 1; neutral_element.Min = 2 * n; neutral_element.Max = -2 * n; tree.resize(n * 4 + 5); } inline void upd(int v, int tl, int tr, T lazy){ tree[v].sum += lazy * (tr - tl + 1); tree[v].Min += lazy; tree[v].Max += lazy; tree[v].isUpdated = true; tree[v].lazy += lazy; } inline void push(int v, int tl, int tr){ if (tl == tr || !tree[v].isUpdated) return; int tm = (tl + tr) >> 1; upd(v << 1, tl, tm, tree[v].lazy); upd(v << 1 | 1, tm + 1, tr, tree[v].lazy); tree[v].lazy = 0; tree[v].isUpdated = false; } inline void update(int v, int tl, int tr, int l, int r, T val){ push(v, tl, tr); if (l <= tl && tr <= r){ upd(v, tl, tr, val); return; } if (tl > r || tr < l) return; int tm = (tl + tr) >> 1; update(v << 1, tl, tm, l, r, val); update(v << 1 | 1, tm + 1, tr, l, r, val); combine(tree[v], tree[v << 1], tree[v << 1 | 1]); } inline void update(int l, int r, T val){ update(1, _begin, _end, l, r, val); } inline node get(int v, int tl, int tr, int l, int r){ push(v, tl, tr); if (l <= tl && tr <= r) return tree[v]; if (tl > r || tr < l) return neutral_element; int tm = (tl + tr) >> 1; node res; combine(res, get(v << 1, tl, tm, l, r), get(v << 1 | 1, tm + 1, tr, l, r)); return res; } inline node get(int l, int r){ return get(1, _begin, _end, l, r); } inline int get(int i){ return get(i, i).sum; } }; int sequence(int N, std::vector<int> A) { A.insert(A.begin(), 0); vector<vector<int>> pos(N + 1); for (int i = 1; i <= N; i++){ pos[A[i]].push_back(i); } int ans = 1; int t = 0; for (int i = 1; i <= N; i++){ if (i == 1 || A[i] == A[i - 1]){ t++; } else { t = 1; } ans = max(ans, t); } SegmentTree<int> st; st.init(N + 1); for (int i = 1; i <= N; i++){ st.update(i, N, 1); } for (int x = 1; x <= N; x++){ if (pos[x].empty()) continue; for (int i : pos[x]){ // making 0 st.update(i, N, -1); } { int i = pos[x].front(), j = pos[x].back(); int f = pos[x].size(); int sum = st.get(j) - st.get(i - 1); if (abs(sum) <= f) ans = max(ans, f); int l1 = st.get(i) - st.get(0, i).Max; int r1 = st.get(i) - st.get(0, i).Min; int l2 = st.get(j, N).Min - st.get(j); int r2 = st.get(j, N).Max - st.get(j); l1 = min(l1, 0), l2 = min(l2, 0); r1 = max(r1, 0), r2 = max(r2, 0); int need; if (sum < -f) { need = -f - sum; } else { need = f - sum; } if (l1 + l2 <= need && need <= r1 + r2) ans = max(ans, f); } for (int i : pos[x]){ // making -1 st.update(i, N, -1); } } return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...