ABC348G 题解
给定长为
输出每个
我用的是
考虑
接下来观察单调性。一图胜千言,下面是
于是,
最终复杂度是
代码:
#include <iostream>
#include <algorithm>
#define int long long
#define fi first
#define se second
using namespace std;
using ll = long long;
using pi = pair<ll, ll>;
const int N = 2e5 + 10;
const ll inf = 1e18;
int qcnt[32 * N], qsum[32 * N], ls[32 * N], rs[32 * N], rt[N], cnt = 0, nr = 0;
ll dsc[N], f[N];
pair<ll, ll> z[N];
static inline ll J (ll x) { return dsc[nr++] = x; }
static inline int Q (ll x) { return lower_bound (dsc, dsc + nr, x) - dsc + 1; }
void upd (int &u, int v, int x, int y, int k, ll val)
{
int mid = (x + y) / 2;
qcnt[u = ++cnt] = qcnt[v] + 1, qsum[u] = qsum[v] + val, ls[u] = ls[v], rs[u] = rs[v];
if (x == y) return;
if (k <= mid) upd (ls[u], ls[v], x, mid, k, val);
else upd (rs[u], rs[v], mid + 1, y, k, val);
}
ll qry (int u, int x, int y, int k)
{
int mid = (x + y) / 2;
if (x == y) return dsc[x - 1] * k;
if (k <= qcnt[rs[u]]) return qry (rs[u], mid + 1, y, k);
else return qry (ls[u], x, mid, k - qcnt[rs[u]]) + qsum[rs[u]];
}
void solve (int l, int r, int ql, int qr)
{
int mid = (ql + qr) / 2, mpos = -1;
ll mval = -inf;
if (l > r || ql > qr) return;
for (int d = max (l, mid); d <= r; d++) {
ll f = qry (rt[d], 1, nr, mid) - z[d].se;
if (f > mval) mval = f, mpos = d;
}
f[mid] = mval;
solve (l, mpos, ql, mid - 1), solve (mpos, r, mid + 1, qr);
}
signed main (void)
{
int n;
ios::sync_with_stdio (false), cin.tie (0), cout.tie (0);
cin >> n;
for (int i = 1; i <= n; i++) cin >> z[i].fi >> z[i].se, J (z[i].fi);
sort (z + 1, z + n + 1, [](pi &x, pi &y) { return x.se < y.se; }), sort (dsc, dsc + nr), nr = unique (dsc, dsc + nr) - dsc;
for (int i = 1; i <= n; i++) upd (rt[i], rt[i - 1], 1, nr, Q (z[i].fi), z[i].fi);
solve (1, n, 1, n);
for (int i = 1; i <= n; i++) cout << f[i] << '\n';
return 0;
}