?
# | Author | Problem | Lang | Verdict | Time | Memory | Sent | Judged | |
---|---|---|---|---|---|---|---|---|---|
225118072 |
Practice: orzdevinwang |
1870G - 31 | C++17 (GCC 9-64) | Accepted | 404 ms | 54664 KB | 2023-09-25 18:08:20 | 2023-09-25 18:08:20 |
#include<bits/stdc++.h> #define L(i, j, k) for(int i = (j); i <= (k); ++i) #define R(i, j, k) for(int i = (j); i >= (k); --i) #define ll long long #define vi vector < int > #define sz(a) ((int) (a).size()) #define ll long long #define ull unsigned long long #define me(a, x) memset(a, x, sizeof(a)) using namespace std; const int N = 1 << 19; int n; int a[N]; int ans[N]; int cnt[N]; struct node { int r; ll k0, b0; // time to go ll k1, b1; }; vector < node > con[N]; int up[N]; void adjust(int x) { while(true) { auto &tmp = con[x].back(); if(tmp.r * tmp.k0 + tmp.b0 > up[x]) { tmp.r = (up[x] - tmp.b0) / tmp.k0; } if(sz(con[x]) > 1 && tmp.r <= con[x][sz(con[x]) - 2].r) { con[x].pop_back(); } else { break; } } R(i, sz(con[x]) - 1, 1) if(con[x][i].r == con[x][i - 1].r + 1) { auto &tmp = con[x][i]; ll v1 = tmp.r * tmp.k0 + tmp.b0; ll v2 = tmp.r * tmp.k1 + tmp.b1; tmp.k0 = 1, tmp.b0 = v1 - tmp.r; tmp.k1 = 1, tmp.b1 = v2 - tmp.r; } assert(sz(con[x]) <= 36); } void upd(int x) { auto &v2 = con[x * 2]; auto &v1 = con[x * 2 + 1]; con[x].clear(); ll cur = 0; int p1 = 0, p2 = 0; while(true) { while(p1 < sz(v1) && v1[p1].r < cur) ++p1; ll valc = cur * v1[p1].k0 + v1[p1].b0; while(p2 < sz(v2) && v2[p2].r < valc) ++p2; if(!(p1 < sz(v1) && p2 < sz(v2))) break; ll r1 = v1[p1].r; ll r2 = (v2[p2].r - v1[p1].b0) / v1[p1].k0; node nw; nw.r = min(r1, r2); nw.k0 = v1[p1].k0 * v2[p2].k0, nw.b0 = v1[p1].b0 * v2[p2].k0 + v2[p2].b0; nw.k1 = v1[p1].k0 * v2[p2].k1 + v1[p1].k1; nw.b1 = v1[p1].b0 * v2[p2].k1 + v1[p1].b1 + v2[p2].b1; cur = nw.r + 1; con[x].emplace_back(nw); } adjust(x); } void make(int x, int p) { node z0, z1; z0.r = cnt[p], z0.k0 = 1, z0.b0 = 0, z0.k1 = -1, z0.b1 = cnt[p]; z1.r = n, z1.k0 = 2, z1.b0 = -cnt[p], z1.k1 = 0, z1.b1 = 0; con[x] = vector < node > {z0, z1}; adjust(x); } void build(int x, int L, int R) { up[x] = n / max(L - 1, 1); if(L == R) { make(x, L); return ; } int mid = (L + R) >> 1; build(x * 2, L, mid); build(x * 2 + 1, mid + 1, R); upd(x); } void modify(int x, int L, int R, int p) { if(L == R) { make(x, L); return ; } int mid = (L + R) >> 1; p <= mid ? modify(x * 2, L, mid, p) : modify(x * 2 + 1, mid + 1, R, p); upd(x); } int need, zero, curp; void slv(int x, int L, int R, int l, int r) { if(l <= L && R <= r) { if(need > curp / R) { need = n * 2; return ; } int pos = 0; while(pos < sz(con[x]) && con[x][pos].r < need) ++pos; if(pos == sz(con[x])) { need = n * 2; } else { zero += con[x][pos].k1 * need + con[x][pos].b1; need = con[x][pos].k0 * need + con[x][pos].b0; } // cout << "after " << L << ' ' << R << " : " << need << ' ' << zero // <<", " << con[x][pos].k0 << ' ' << con[x][pos].b0 << ' ' << // con[x][pos].k1 << ' ' << con[x][pos].b1 << endl; return ; } int mid = (L + R) >> 1; if(r > mid) slv(x * 2 + 1, mid + 1, R, l, r); if(l <= mid) slv(x * 2, L, mid, l, r); } int a1; void Main() { cin >> n; L(i, 1, n) { cin >> a[i]; } a1 = a[1]; L(i, 1, n) { if(a[i] > n) { a[i] = 0; } } L(i, 0, n) { cnt[i] = 0; } build(1, 0, n); int ns = 1; int SUM = 0; L(i, 1, n) { if(a[i] >= ns) { ++SUM; } ++cnt[a[i]]; modify(1, 0, n, a[i]); curp = i; while(ns <= i) { // cout << "checking " << ns << endl; need = 1, zero = SUM + cnt[0]; if(1 < ns) slv(1, 0, n, 1, ns - 1); if(zero < need) { break; } SUM -= cnt[ns]; ++ns; } ans[i] = ns - 1; } ans[1] = max(ans[1], a1); L(i, 1, n) { cout << ans[i] << ' '; } cout << '\n'; } int main() { ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin >> t; while(t--) Main(); return 0; }
?
?
?
?