Submission #900241

#TimeUsernameProblemLanguageResultExecution timeMemory
900241starchanSequence (APIO23_sequence)C++17
100 / 100
904 ms103832 KiB
#include "sequence.h" #include<bits/stdc++.h> using namespace std; #define in pair<int, int> #define f first #define s second #define pb push_back #define pob pop_back #define INF (int)1e6 #define MX (int)3e5+5 #define fast() ios_base::sync_with_stdio(false); cin.tie(NULL) in extremise(const in &a, const in&b) { return {min(a.f, b.f), max(a.s, b.s)}; } void increment(int delta, in &a) { if(a.f == INF) return; a.f+=delta; a.s+=delta; return; } struct extremal_tree { vector<in> tree; void init(int n) { tree.assign(4*n+8, {INF, -INF}); return; } void upd(int v, int pos, int id, int l, int r) { if(l == r) { tree[id] = extremise(tree[id], {v, v}); return; } int m = (l+r)/2; if(pos <= m) upd(v, pos, 2*id, l, m); else upd(v, pos, 2*id+1, m+1, r); tree[id] = extremise(tree[2*id], tree[2*id+1]); return; } in val(int ql, int qr, int id, int l, int r) { if(r < ql || qr < l) return {INF, -INF}; if(ql <= l && r <= qr) return tree[id]; int m = (l+r)/2; in a = val(ql, qr, 2*id, l, m); in b = val(ql, qr, 2*id+1, m+1, r); return extremise(a, b); } }; struct lazy_extremal_tree { vector<in> tree; vector<int> lazy; void init(int n) { tree.assign(4*n+8, {INF, -INF}); lazy.assign(4*n+8, 0); return; } void push(int id) { increment(lazy[id], tree[2*id]); increment(lazy[id], tree[2*id+1]); lazy[2*id]+=lazy[id]; lazy[2*id+1]+=lazy[id]; lazy[id] = 0; return; } void upd(int v, int pos, int id, int l, int r) { if(l == r) { tree[id] = extremise(tree[id], {v, v}); return; } int m = (l+r)/2; if(pos <= m) upd(v, pos, 2*id, l, m); else upd(v, pos, 2*id+1, m+1, r); tree[id] = extremise(tree[2*id], tree[2*id+1]); return; } void upd2(int delta, int ql, int qr, int id, int l, int r) { if(qr < l || r < ql) return; if(ql <= l && r <= qr) { lazy[id]+=delta; increment(delta, tree[id]); return; } push(id); int m = (l+r)/2; upd2(delta, ql, qr, 2*id, l, m); upd2(delta, ql, qr, 2*id+1, m+1, r); tree[id] = extremise(tree[2*id], tree[2*id+1]); return; } in val(int ql, int qr, int id, int l, int r) { if(r < ql || qr < l) return {INF, -INF}; if(ql <= l && r <= qr) return tree[id]; push(id); int m = (l+r)/2; in a = val(ql, qr, 2*id, l, m); in b = val(ql, qr, 2*id+1, m+1, r); return extremise(a, b); } }; vector<int> compressor; int compress(int n) { return lower_bound(compressor.begin(), compressor.end(), n)-compressor.begin(); } int solve(int n, vector<in> &ac, vector<in> &bd)//no assuming compression! { extremal_tree work; compressor.clear(); work.init(2*n); vector<int> v; //compress begin for(auto [a, c]: ac) v.pb(c); for(auto [b, d]: bd) v.pb(d); sort(v.begin(), v.end()); compressor.pb(v[0]); for(int k = 1; k < v.size(); k++) { if(v[k] != v[k-1]) compressor.pb(v[k]); } //compress over vector<in> a; vector<in> b; for(int i = 0; i < n; i++) a.pb({ac[i].f, i}); for(int i = 0; i < n; i++) b.pb({bd[i].f, i}); sort(a.begin(), a.end()); sort(b.begin(), b.end()); int ans = -INF; int l = 0; for(int i = 0; i < n; i++) { while((l < n) && (a[l].f <= b[i].f)) { work.upd(a[l].s, compress(ac[a[l].s].s), 1, 0, 2*n); l++; } auto [m, M] = work.val(0, compress(bd[b[i].s].s), 1, 0, 2*n); if(m != INF) ans = max(abs(m-b[i].s), ans); if(M != -INF) ans = max(abs(M-b[i].s), ans); } return ans; } int sequence(int n, vector<int> a) { lazy_extremal_tree work; work.init(n); vector<int> adj[n+1]; for(int i = 1; i <= n; i++) adj[a[i-1]].pb(i); for(int i = 0; i <= n; i++) work.upd(-i, i, 1, 0, n); int ans = 0; for(int i = 1; i <= n; i++) { int m = adj[i].size(); for(int k: adj[i-1]) work.upd2(+1, k, n, 1, 0, n); for(int k: adj[i]) work.upd2(+1, k, n, 1, 0, n); vector<int> bb(m+2); bb[0] = 0; bb[m+1] = n+1; for(int j = 1; j <= m; j++) bb[j] = adj[i][j-1]; vector<in> ac(m+1), bd(m+1); for(int j = 0; j <= m; j++) { auto [a, b] = work.val(bb[j], bb[j+1]-1, 1, 0, n); ac[j] = {a+j, j-b}; bd[j] = {b+j, j-a}; } int ok = solve(m+1, ac, bd); ans = max(ans, ok); } return ans; } /*vector<int> c; int W(int l, int r, int x) { int cnt = 0; for(int i = l; i <= r; i++) cnt+=(c[i] == x); return cnt; } int median_freq(int l, int r) { vector<int> v; int k = r-l; for(int i = l; i <= r; i++) v.pb(c[i]); sort(v.begin(), v.end()); int t = k/2; int tp = t+k%2; return max(W(l, r, v[t]), W(l, r, v[tp])); } signed main() { fast(); int t; cin >> t; while(t--) { c.clear(); int n; cin >> n; vector<int> a(n); for(int &k: a) { cin >> k; c.pb(k); } int ans = sequence(n, a); int tit = 0; for(int l = 0; l < n; l++) { for(int r = l; r < n; r++) tit = max(tit, median_freq(l, r)); } if(ans != tit) { cout << "WTF !!!" << endl; printf("Fake = %d, real = %d", ans, tit); } assert(ans==tit); cout << "All good!" << endl; } return 0; }*/

Compilation message (stderr)

sequence.cpp: In function 'int solve(int, std::vector<std::pair<int, int> >&, std::vector<std::pair<int, int> >&)':
sequence.cpp:143:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  143 |  for(int k = 1; k < v.size(); k++)
      |                 ~~^~~~~~~~~~
#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...