Submission #1072027

#TimeUsernameProblemLanguageResultExecution timeMemory
1072027mickey080929Arranging Tickets (JOI17_arranging_tickets)C++17
100 / 100
1093 ms17404 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef pair<ll,ll> pll; struct SegmentTree{ vector<ll> tree; vector<ll> lazy; void init(ll n) { ll sz = 1 << __lg(n-1) + 2; tree.assign(sz, 0); lazy.assign(sz, 0); } void build(ll node, ll s, ll e, vector<ll> &v) { lazy[node] = 0; if (s == e) { tree[node] = v[s]; return; } ll mid = s + e >> 1; build(node*2, s, mid, v); build(node*2+1, mid+1, e, v); tree[node] = max(tree[node*2], tree[node*2+1]); } void propagate(ll node, ll s, ll e) { tree[node] += lazy[node]; if (s != e) { lazy[node*2] += lazy[node]; lazy[node*2+1] += lazy[node]; } lazy[node] = 0; } void update(ll node, ll s, ll e, ll l, ll r, ll v) { propagate(node, s, e); if (l > e || s > r) return; if (l <= s && e <= r) { lazy[node] = v; propagate(node, s, e); return; } ll mid = s + e >> 1; update(node*2, s, mid, l, r, v); update(node*2+1, mid+1, e, l, r, v); tree[node] = max(tree[node*2], tree[node*2+1]); } ll query(ll node, ll s, ll e, ll l, ll r) { propagate(node, s, e); if (l > e || s > r) return 0; if (l <= s && e <= r) return tree[node]; ll mid = s + e >> 1; return max(query(node*2, s, mid, l, r), query(node*2+1, mid+1, e, l, r)); } }; struct FenwickTree{ vector<ll> tree; void init(ll n) { tree.assign(n+1, 0); } void upd(ll i, ll v, ll n) { i ++; while (i <= n) { tree[i] += v; i += i & -i; } } ll qry(ll i) { i ++; ll ret = 0; while (i) { ret += tree[i]; i -= i & -i; } return ret; } }; struct DisjointSet{ vector<ll> par; vector<ll> lft; void init(ll n) { par.resize(n); iota(par.begin(), par.end(), 0); lft.resize(n); iota(lft.begin(), lft.end(), 0); } ll Find(ll x) { if (x == par[x]) return x; return par[x] = Find(par[x]); } void Union(ll l, ll r) { l = Find(l); r = Find(r); lft[r] = lft[l]; par[l] = r; } }; FenwickTree seg; DisjointSet dsu; SegmentTree seg2; struct Move{ ll A, B, C; }; ll N, M; ll solve(ll X, vector<ll> &use, vector<Move> &a) { seg.init(N); dsu.init(N); ll j = 0; ll ans = 0; for (ll i=0; i<N-1; i++) { ll t = i-1; while (t >= 0) { if (use[t] + seg.qry(t) <= use[i]) { dsu.Union(t, i); } else break; t = dsu.lft[i] - 1; } while (j < M && a[j].B-1 == i) { ll p = dsu.Find(a[j].A); ll mx = use[p] + seg.qry(p); if (mx == X) { j ++; continue; } ll temp = min(a[j].C, (X - mx) / 2); seg.upd(a[j].A, temp * 2, N); seg.upd(a[j].B, -temp * 2, N); ans += temp; ll cur = mx + temp * 2; t = dsu.lft[p] - 1; while (t >= 0) { if (use[t] + seg.qry(t) <= cur) { dsu.Union(t, p); } else break; t = dsu.lft[p] - 1; } j ++; } } return ans; } int main() { ios_base :: sync_with_stdio(false); cin.tie(NULL); cin >> N >> M; vector<Move> a(M); ll tot = 0; for (ll i=0; i<M; i++) { cin >> a[i].A >> a[i].B >> a[i].C; a[i].A --; a[i].B --; if (a[i].A > a[i].B) swap(a[i].A, a[i].B); tot += a[i].C; } sort(a.begin(), a.end(), [&] (Move &u, Move &v) { if (u.B == v.B) return u.A > v.A; return u.B < v.B; }); vector<ll> use(N, 0); seg2.init(N); for (ll i=0; i<M; i++) { seg2.update(1, 0, N-1, a[i].B, N-1, a[i].C); seg2.update(1, 0, N-1, 0, a[i].A-1, a[i].C); } for (ll i=0; i<N; i++) { use[i] = seg2.query(1, 0, N-1, i, i); } ll ans = tot; ll lo = tot, hi = tot + min(1000000000LL, tot); while (lo <= hi) { ll mid = (lo + hi) / 2; ll ret1 = mid - solve(mid, use, a); ll ret2 = mid+1 - solve(mid+1, use, a); ans = min({ans, ret1, ret2}); if (ret1 > ret2) { lo = mid + 2; } else { hi = mid - 1; } } cout << ans << '\n'; }
#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...