Cod sursa(job #2887956)

Utilizator Vlad_AnicaAnica-Popa Vlad-Ioan Vlad_Anica Data 10 aprilie 2022 14:51:24
Problema A+B Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <map>
#define fin cin
#define fout cout


using namespace std;

//ifstream fin("f.in");
//ofstream fout("f.out");

const int NMAX = 3e6, BS = (1 << 11) - 1, BB = 11, MMAX = 1e6;


struct pack2 {
    int val, tag;
};
struct pack {
    int l, r;
};
struct cmp {
    public: bool operator()(const pack2 &a, const pack2 &b) { //returnez 1 daca a are prioritatea stric mai mare  ca b
        return a.val < b.val;
    };
};

pack add[10 * NMAX + 1];
bool ison[15 * NMAX + 1];

multimap<int, pack2> blocks[MMAX / (BS + 1) + 10];
priority_queue<pack2, vector<pack2>, cmp> rs[MMAX + 1000];

int getb(int pos);
int gfirst(int block);
int glast(int block);
void ins(int l, int r);
void query(int t, int type);


int n, nrb, glbtag; ///globalele

int main()
{
    int q;
    int mx = 0;

    scanf("%d%d", &n, &q);

    int l, r, glbtag = 0;
    for (int i = 0; i < n; i++) {
        scanf("%d%d", &l, &r);
        l--, r--;
        if (l != r) {
            mx = max(mx, r);
            ins(l, r);
        }
    }
    int t, type;
    for (int i = 0; i < q; i++) {
        scanf("%d%d", &type, &t);
        t--;
        if (t <= mx)
            query(t, type);
    }

    long long ans = 0;
    for (l = 0; l <= mx; l++)
        while (!rs[l].empty()) {
            if (ison[rs[l].top().tag])
                ans = ans + rs[l].top().val - l;
            rs[l].pop();
        }
    cout << ans;

    return 0;
}

int getb(int pos) {
    return pos >> BB;
}
int gfirst(int block) {
    return block << BB;
}
int glast(int block) {
    return (block << BB) + BS;
}
void ins(int l, int r) {
    rs[l].push({r, glbtag});
    blocks[getb(l)].insert(pair<int, pack2>(r, {l, glbtag}));
    ison[glbtag] = 1;
    glbtag++;
}

void query(int t, int type) {

    int bi = 0;
    int ind = 0;
    while (glast(bi) < t) {
        if (!blocks[bi].empty()) {
            auto it = blocks[bi].end();
            if (it != blocks[bi].begin())
                it--;
            while (it != blocks[bi].begin() && (it -> first) > t) {
                auto cpit = it;
                cpit--;
                if (ison[it -> second.tag] == 1) {
                    if (it -> first != t)
                        add[ind++] = {t, it -> first};
                    if (it -> second.val != t)
                        add[ind++] = {it -> second.val, t};
                }
                ison[it -> second.tag] = 0;
                blocks[bi].erase(it);
                it = cpit;

            }
            if (it -> first > t) {
                if (ison[it -> second.tag]) {
                    if (it -> first != t)
                        add[ind++] = {t, it -> first};
                    if (it -> second.val != t)
                        add[ind++] = {it -> second.val, t};
                }
                ison[it -> second.tag] = 0;
                blocks[bi].erase(it);

            }
        }
        bi++;
    }
    int pos = gfirst(bi);
    for (int i = pos; i < t; i++) {
        while (!rs[i].empty() && rs[i].top().val > t) {
            if (ison[rs[i].top().tag] == 1) {
                if (t != rs[i].top().val)
                    add[ind++] = {t, rs[i].top().val};
                if (t != i)
                    add[ind++] = {i, t};
            }
            ison[rs[i].top().tag] = 0;
            rs[i].pop();
        }
    }

    if (type == 1)
        for (int i = 0; i < ind; i++)
            ins(add[i].l, add[i].r);
}