제출 #755104

#제출 시각아이디문제언어결과실행 시간메모리
755104IloveN서열 (APIO23_sequence)C++17
100 / 100
1187 ms50016 KiB
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define all(vr) vr.begin(), vr.end() using ll = long long; using ld = long double; using pii = pair<int, int>; using vi = vector<int>; using vl = vector<ll>; const int N = 5e5 + 10; struct segment_tree_max { int it[N * 4], lazy[N * 4], n, u, v, x; int combine(int obj1, int obj2) { return max(obj1, obj2);} void build(int id, int l, int r) { if (l == r) { it[id] = 0; lazy[id] = 0; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build((id << 1) | 1, mid + 1, r); it[id] = combine(it[id << 1], it[(id << 1) | 1]); lazy[id] = 0; } void init(int len) { n = len; build(1, 1, n); } void apply(int id, int val) { it[id] += val; lazy[id] += val; } void push(int id) { apply(id << 1, lazy[id]); apply((id << 1) | 1, lazy[id]); lazy[id] = 0; } void update(int id, int l, int r) { if (l > v || r < u) return; if (u <= l && r <= v) { apply(id, x); return; } int mid = (l + r) >> 1; push(id); update(id << 1, l, mid); update((id << 1) | 1, mid + 1, r); it[id] = combine(it[id << 1], it[(id << 1) | 1]); } int get(int id, int l, int r) { if (l > v || r < u) return -1e9; if (u <= l && r <= v) return it[id]; int mid = (l + r) >> 1; push(id); return combine(get(id << 1, l, mid), get((id << 1) | 1, mid + 1, r)); } int lw(int id, int l, int r) { if (l > v || r < u || it[id] < x) return -1; if (l == r) return l; int mid = (l + r) >> 1; push(id); int tmp = lw(id << 1, l, mid); if (tmp != -1) return tmp; return lw((id << 1) | 1, mid + 1, r); } void Update(int l, int r, int val) { u = l; v = r; x = val; update(1, 1, n); } int Get(int l, int r) { u = l; v = r; if (l > r) return 0; return get(1, 1, n); } int Lower_bound(int l, int r, int val) { u = l; v = r; x = val; return lw(1, 1, n); } } seg_mx; struct segment_tree_min { int it[N * 4], lazy[N * 4], n, u, v, x; int combine(int obj1, int obj2) { return min(obj1, obj2);} void build(int id, int l, int r) { if (l == r) { it[id] = 0; lazy[id] = 0; return; } int mid = (l + r) >> 1; build(id << 1, l, mid); build((id << 1) | 1, mid + 1, r); it[id] = combine(it[id << 1], it[(id << 1) | 1]); lazy[id] = 0; } void init(int len) { n = len; build(1, 1, n); } void apply(int id, int val) { it[id] += val; lazy[id] += val; } void push(int id) { apply(id << 1, lazy[id]); apply((id << 1) | 1, lazy[id]); lazy[id] = 0; } void update(int id, int l, int r) { if (l > v || r < u) return; if (u <= l && r <= v) { apply(id, x); return; } int mid = (l + r) >> 1; push(id); update(id << 1, l, mid); update((id << 1) | 1, mid + 1, r); it[id] = combine(it[id << 1], it[(id << 1) | 1]); } int get(int id, int l, int r) { if (l > v || r < u) return 1e9; if (u <= l && r <= v) return it[id]; int mid = (l + r) >> 1; push(id); return combine(get(id << 1, l, mid), get((id << 1) | 1, mid + 1, r)); } int lw(int id, int l, int r) { if (l > v || r < u || it[id] > x) return -1; if (l == r) return l; int mid = (l + r) >> 1; push(id); int tmp = lw(id << 1, l, mid); if (tmp != -1) return tmp; return lw((id << 1) | 1, mid + 1, r); } void Update(int l, int r, int val) { u = l; v = r; x = val; update(1, 1, n); } int Get(int l, int r) { u = l; v = r; if (l > r) return 0; return get(1, 1, n); } int Lower_bound(int l, int r, int val) { u = l; v = r; x = val; return lw(1, 1, n); } } seg_mn; int a[N]; vi pos[N]; int sequence(int n, vi arr) { for (int i = 1; i <= n; ++i) a[i] = arr[i - 1]; for (int i = 1; i <= n; ++i) pos[i].clear(); for (int i = 1; i <= n; ++i) pos[a[i]].eb(i); seg_mx.init(n); seg_mn.init(n); for (int i = 1; i <= n; ++i) { seg_mx.Update(i, n, -1); seg_mn.Update(i, n, -1); } int res = 0; for (int i = 1; i <= n; ++i) { for (int j = 0; j < (int)pos[i].size(); ++j) { int x = pos[i][j]; int vl = seg_mn.Get(x, x); int vr = seg_mn.Get(x, n); if (vr <= 0 && vl >= -(j + 1) * 2) res = max(res, j + 1); else if (vr > 0) { int l = seg_mx.Lower_bound(1, x - 1, vr); if (l != -1) { int t = upper_bound(all(pos[i]), l) - pos[i].begin(); res = max(res, j - t + 1); } } } for (int x : pos[i]) { seg_mx.Update(x, n, 2); seg_mn.Update(x, n, 2); } for (int j = 0; j < (int)pos[i].size(); ++j) { int x = pos[i][j]; int vl = seg_mx.Get(x, x); int vr = seg_mx.Get(x, n); if (vr >= 0 && vl <= (j + 1) * 2) res = max(res, j + 1); else if (vr < 0) { int l = seg_mn.Lower_bound(1, x - 1, vr); if (l != -1) { int t = upper_bound(all(pos[i]), l) - pos[i].begin(); res = max(res, j - t + 1); } } } } return res; }
#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...