This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub maspypy/library
#include "ds/monotone/prefix_add_append_get_max.hpp"
#include "ds/unionfind/unionfind.hpp" // prefix add / 末尾追加 / 全体 max // https://qoj.ac/contest/1472/problem/7905 struct Prefix_Add_Append_Get_Max { int n; UnionFind uf; vc<pair<int, int>> range; vi dat; ll max; Prefix_Add_Append_Get_Max(int max_n) : n(max_n), uf(max_n), range(max_n), max(-infty<ll>) {} void append(int i, ll x) { assert(i == len(dat) && i < n); range[i] = {i, i + 1}; if (i == 0) { max = x; dat.eb(x); return; } if (x > max) { dat.eb(x - max); max = x; return; } dat.eb(0); merge(i); return; } void merge(int i) { int a = uf[i - 1], b = uf[i]; assert(a != b); uf.merge(a, b); int c = uf[a]; range[c].fi = range[a].fi, range[c].se = range[b].se; } // [0,i), +x void prefix_add(int i, ll x) { if (i == 0) return; assert(i <= len(dat) && x >= 0); dat[0] += x, max += x; while (x > 0) { auto [l, r] = range[uf[i]]; int p = (l == i ? l : r); if (p == len(dat)) return; ll y = dat[p]; ll z = min(x, y); dat[p] -= z, x -= z, max -= z; if (dat[p] == 0) { merge(p); continue; } } } ll get_max() { return max; } };
#line 2 "ds/unionfind/unionfind.hpp" struct UnionFind { int n, n_comp; vc<int> dat; // par or (-size) UnionFind(int n = 0) { build(n); } void build(int m) { n = m, n_comp = m; dat.assign(n, -1); } void reset() { build(n); } int operator[](int x) { while (dat[x] >= 0) { int pp = dat[dat[x]]; if (pp < 0) { return dat[x]; } x = dat[x] = pp; } return x; } ll size(int x) { x = (*this)[x]; return -dat[x]; } bool merge(int x, int y) { x = (*this)[x], y = (*this)[y]; if (x == y) return false; if (-dat[x] < -dat[y]) swap(x, y); dat[x] += dat[y], dat[y] = x, n_comp--; return true; } vc<int> get_all() { vc<int> A(n); FOR(i, n) A[i] = (*this)[i]; return A; } }; #line 2 "ds/monotone/prefix_add_append_get_max.hpp" // prefix add / 末尾追加 / 全体 max // https://qoj.ac/contest/1472/problem/7905 struct Prefix_Add_Append_Get_Max { int n; UnionFind uf; vc<pair<int, int>> range; vi dat; ll max; Prefix_Add_Append_Get_Max(int max_n) : n(max_n), uf(max_n), range(max_n), max(-infty<ll>) {} void append(int i, ll x) { assert(i == len(dat) && i < n); range[i] = {i, i + 1}; if (i == 0) { max = x; dat.eb(x); return; } if (x > max) { dat.eb(x - max); max = x; return; } dat.eb(0); merge(i); return; } void merge(int i) { int a = uf[i - 1], b = uf[i]; assert(a != b); uf.merge(a, b); int c = uf[a]; range[c].fi = range[a].fi, range[c].se = range[b].se; } // [0,i), +x void prefix_add(int i, ll x) { if (i == 0) return; assert(i <= len(dat) && x >= 0); dat[0] += x, max += x; while (x > 0) { auto [l, r] = range[uf[i]]; int p = (l == i ? l : r); if (p == len(dat)) return; ll y = dat[p]; ll z = min(x, y); dat[p] -= z, x -= z, max -= z; if (dat[p] == 0) { merge(p); continue; } } } ll get_max() { return max; } };