一開始的時候顯然第\(i\)天之前能夠放\(i\)個任務是吧,而後考慮用一棵線段樹維護這個數量,設天天的這個值爲\(lev(i)\)
考慮在\(t\)這個截止時間位置放了一個任務,那\((t,n)\)這個區間的$ lev(i)$ 都要減去\(1\)。 ui
設插入的終止時間爲\(t\),這個任務的價值爲\(p\)。那如何插入呢?spa
至於這個集合怎麼維護,顯然線段樹套個multiset就好了code
至於代碼爲何這麼長
固然是爲了更好地裝逼說明啦!
記得點贊啊,我就沒收過贊。。。
下次必定的走開(bushiget
#include <set> #include <cstdio> #include <utility> #include <algorithm> using namespace std; #define R register #define LL long long #define IT multiset<int>::iterator const int MAXN = 3e5 + 10; const int inf = 1e9 + 10; inline int read() { char a = getchar(); int x = 0, f = 1; for (; a > '9' || a < '0'; a = getchar()) if (a == '-') f = -1; for (; a >= '0' && a <= '9'; a = getchar()) x = x * 10 + a - '0'; return x * f; } inline char getc() { char a = getchar(); while (a != 'A' && a != 'D') a = getchar(); return a; } int n, m; LL Ans; struct Round { int l, r, va; }; class Tree_for_value { private: int tag[MAXN << 2]; Round mn[MAXN << 2]; inline int ls(int x); inline int rs(int x); inline void update(int x); inline void get(int x, int k); inline void pushdown(int x); public: inline Round ask(int x, int l, int r, int Le, int Ri); inline void chg(int x, int l, int r, int Le, int Ri, int k); inline void build(int x, int l, int r); } T1; class Tree_for_mintask { private: multiset<int> st[MAXN << 2]; pair<int, int> mn[MAXN << 2]; inline int ls(int x); inline int rs(int x); inline void update(int x); public: inline void build(int x, int l, int r); inline void insert(int x, int l, int r, int ad, int p); inline void del(int x, int l, int r, int ad, int p); inline pair<int, int> ask(int x, int l, int r, int Le, int Ri); inline int have(int x, int l, int r, int ad, int p); } T2; class Tree_for_maxtask { private: multiset<int> st[MAXN << 2]; pair<int, int> mx[MAXN << 2]; inline int ls(int x); inline int rs(int x); inline void update(int x); public: inline void build(int x, int l, int r); inline void insert(int x, int l, int r, int ad, int p); inline void del(int x, int l, int r, int ad, int p); inline pair<int, int> ask(int x, int l, int r, int Le, int Ri); } T3; int main() { freopen("d.in", "r", stdin); freopen("d.out", "w", stdout); n = read(); m = read(); T1.build(1, 1, n); T2.build(1, 1, n); T3.build(1, 1, n); char op; int t, p; while (m--) { op = getc(); t = read(); p = read(); if (op == 'A') { Round pir = T1.ask(1, 1, n, t, n); if (pir.va > 0) { Ans += p; T1.chg(1, 1, n, t, n, -1); T2.insert(1, 1, n, t, p); } else { int id = pir.l; pair<int, int> tmp = T2.ask(1, 1, n, 1, id); if (tmp.first > p) T3.insert(1, 1, n, t, p); else { Ans += p - tmp.first; T2.del(1, 1, n, tmp.second, tmp.first); T3.insert(1, 1, n, tmp.second, tmp.first); T1.chg(1, 1, n, tmp.second, n, 1); T2.insert(1, 1, n, t, p); T1.chg(1, 1, n, t, n, -1); } } } else { if (T2.have(1, 1, n, t, p) == 0) T3.del(1, 1, n, t, p); else { Ans -= p; T2.del(1, 1, n, t, p); T1.chg(1, 1, n, t, n, 1); Round tmp = T1.ask(1, 1, n, 1, n); int id = tmp.va <= 0 ? tmp.r : 0; if (id != n) { pair<int, int> tmp = T3.ask(1, 1, n, id + 1, n); if (tmp.first != -inf) { T3.del(1, 1, n, tmp.second, tmp.first); T2.insert(1, 1, n, tmp.second, tmp.first); T1.chg(1, 1, n, tmp.second, n, -1); Ans += tmp.first; } } } } printf("%lld\n", Ans); } return 0; } inline int Tree_for_value::ls(int x) { return x << 1; } inline int Tree_for_value::rs(int x) { return x << 1 | 1; } inline void Tree_for_value::update(int x) { if (mn[ls(x)].va == mn[rs(x)].va) { mn[x].va = mn[ls(x)].va; mn[x].l = mn[ls(x)].l; mn[x].r = mn[rs(x)].r; } if (mn[ls(x)].va < mn[rs(x)].va) mn[x] = mn[ls(x)]; if (mn[ls(x)].va > mn[rs(x)].va) mn[x] = mn[rs(x)]; } inline void Tree_for_value::get(int x, int k) { tag[x] += k; mn[x].va += k; } inline void Tree_for_value::pushdown(int x) { if (tag[x]) { get(ls(x), tag[x]); get(rs(x), tag[x]); tag[x] = 0; } } inline void Tree_for_value::build(int x, int l, int r) { if (l == r) { mn[x] = {l, l, l}; return; } int mid = l + r; mid >>= 1; build(ls(x), l, mid); build(rs(x), mid + 1, r); update(x); } inline void Tree_for_value::chg(int x, int l, int r, int Le, int Ri, int k) { if (l >= Le && r <= Ri) { get(x, k); return; } pushdown(x); int mid = l + r; mid >>= 1; if (Le <= mid) chg(ls(x), l, mid, Le, Ri, k); if (Ri > mid) chg(rs(x), mid + 1, r, Le, Ri, k); update(x); } inline Round Tree_for_value::ask(int x, int l, int r, int Le, int Ri) { if (l >= Le && r <= Ri) return mn[x]; pushdown(x); int mid = l + r; mid >>= 1; Round ans; if (Le > mid) ans = ask(rs(x), mid + 1, r, Le, Ri); else if (Ri <= mid) return ans = ask(ls(x), l, mid, Le, Ri); else { Round lef = ask(ls(x), l, mid, Le, Ri), rig = ask(rs(x), mid + 1, r, Le, Ri); if (lef.va < rig.va) ans = lef; if (lef.va > rig.va) ans = rig; if (lef.va == rig.va) { ans.l = lef.l; ans.r = rig.r; ans.va = lef.va; } } update(x); return ans; } inline int Tree_for_mintask::ls(int x) { return x << 1; } inline int Tree_for_mintask::rs(int x) { return x << 1 | 1; } inline void Tree_for_mintask::update(int x) { if (mn[ls(x)].first <= mn[rs(x)].first) mn[x] = mn[ls(x)]; else mn[x] = mn[rs(x)]; } inline void Tree_for_mintask::build(int x, int l, int r) { if (l == r) { mn[x] = make_pair(inf, l); return; } int mid = l + r; mid >>= 1; build(ls(x), l, mid); build(rs(x), mid + 1, r); update(x); } inline void Tree_for_mintask::insert(int x, int l, int r, int ad, int p) { if (l == r) { st[x].insert(p); mn[x].first = min(mn[x].first, p); return; } int mid = l + r; mid >>= 1; if (ad <= mid) insert(ls(x), l, mid, ad, p); else insert(rs(x), mid + 1, r, ad, p); update(x); } inline void Tree_for_mintask::del(int x, int l, int r, int ad, int p) { if (l == r) { st[x].erase(st[x].find(p)); if (st[x].size()) mn[x].first = *st[x].begin(); else mn[x].first = inf; return; } int mid = l + r; mid >>= 1; if (ad <= mid) del(ls(x), l, mid, ad, p); if (ad > mid) del(rs(x), mid + 1, r, ad, p); update(x); } inline pair<int, int> Tree_for_mintask::ask(int x, int l, int r, int Le, int Ri) { if (l >= Le && r <= Ri) return mn[x]; int mid = l + r; mid >>= 1; if (Le > mid) return ask(rs(x), mid + 1, r, Le, Ri); if (Ri <= mid) return ask(ls(x), l, mid, Le, Ri); pair<int, int> lef = ask(ls(x), l, mid, Le, Ri), rig = ask(rs(x), mid + 1, r, Le, Ri); if (lef.first <= rig.first) return lef; return rig; } inline int Tree_for_mintask::have(int x, int l, int r, int ad, int p) { if (l == r) return st[x].find(p) != st[x].end(); int mid = l + r; mid >>= 1; if (ad <= mid) return have(ls(x), l, mid, ad, p); else return have(rs(x), mid + 1, r, ad, p); } inline int Tree_for_maxtask::ls(int x) { return x << 1; } inline int Tree_for_maxtask::rs(int x) { return x << 1 | 1; } inline void Tree_for_maxtask::update(int x) { if (mx[ls(x)].first > mx[rs(x)].first) mx[x] = mx[ls(x)]; else mx[x] = mx[rs(x)]; } inline void Tree_for_maxtask::build(int x, int l, int r) { if (l == r) { mx[x] = make_pair(-inf, l); return; } int mid = l + r; mid >>= 1; build(ls(x), l, mid); build(rs(x), mid + 1, r); update(x); } inline void Tree_for_maxtask::insert(int x, int l, int r, int ad, int p) { if (l == r) { st[x].insert(p); mx[x].first = max(mx[x].first, p); return; } int mid = l + r; mid >>= 1; if (ad <= mid) insert(ls(x), l, mid, ad, p); else insert(rs(x), mid + 1, r, ad, p); update(x); } inline void Tree_for_maxtask::del(int x, int l, int r, int ad, int p) { if (l == r) { st[x].erase(st[x].find(p)); if (st[x].size()) { IT it = st[x].end(); it--; mx[x].first = *it; } else mx[x].first = -inf; return; } int mid = l + r; mid >>= 1; if (ad <= mid) del(ls(x), l, mid, ad, p); if (ad > mid) del(rs(x), mid + 1, r, ad, p); update(x); } inline pair<int, int> Tree_for_maxtask::ask(int x, int l, int r, int Le, int Ri) { if (l >= Le && r <= Ri) return mx[x]; int mid = l + r; mid >>= 1; if (Le > mid) return ask(rs(x), mid + 1, r, Le, Ri); if (Ri <= mid) return ask(ls(x), l, mid, Le, Ri); pair<int, int> lef = ask(ls(x), l, mid, Le, Ri), rig = ask(rs(x), mid + 1, r, Le, Ri); if (lef.first > rig.first) return lef; return rig; }