Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- int sz[N];
- vector <pii> mn[N];
- vector <vector <pii>> g[N];
- void fill_v(int id, int block) {
- while (sz(g[id]) <= block)g[id].pb({});
- while (sz(mn[id]) <= block)mn[id].pb({inf, inf});
- }
- void build(int id) {
- vector <pii> vec;
- for (int block = 0;block < sz(g[id]);block++) {
- for (auto val : g[id][block])vec.pb(val);
- }
- g[id].clear(), mn[id].clear();
- for (int i = 0;i < sz(vec);i++) {
- int block = i / K;
- fill_v(id, block);
- g[id][block].pb(vec[i]);
- if (i % K == 0)mn[id].pb(vec[i]);
- }
- }
- bool bigger(pii val, pii x) {
- return (val.x > x.x) || (val.x == x.x && val.y >= x.y);
- }
- pii get(pii val, int id) {
- int b = 0;
- fill_v(id, b + 1);
- while (b + 1 < sz(mn[id]) && bigger(val, mn[id][b + 1]))b++;
- int pos = 0;
- while (pos < sz(g[id][b]) && bigger(val, g[id][b][pos]))pos++;
- return {b, pos};
- }
- void add(pii val, int id) {
- int block, pos;
- tie(block, pos) = get(val, id);
- vector <pii> vals;
- fill_v(id, block);
- int cnt = sz(g[id][block]) - pos;
- while (cnt--)vals.pb(g[id][block].back()), g[id][block].pop_back();
- mn[id][block] = min(mn[id][block], val);
- g[id][block].pb(val), sz[id]++;
- while (!vals.empty())g[id][block].pb(vals.back()), vals.pop_back();
- if (sz(g[id][block]) > 2 * K)build(id);
- }
- void del(pii val, int id) {
- int block, pos;
- tie(block, pos) = get(val, id);
- vector <pii> vals;
- fill_v(id, block);
- int cnt = sz(g[id][block]) - pos;
- while (cnt--)vals.pb(g[id][block].back()), g[id][block].pop_back();
- if (!g[id][block].empty())g[id][block].pop_back(), sz[id]--;
- while (!vals.empty())g[id][block].pb(vals.back()), vals.pop_back();
- if (sz(g[id][block]) == 0)build(id);
- }
Advertisement
Add Comment
Please, Sign In to add comment