Submission #1328436

#TimeUsernameProblemLanguageResultExecution timeMemory
1328436Mauricio_CruzExhibition (JOI19_ho_t2)C++20
0 / 100
2 ms3396 KiB
#include <bits/stdc++.h>
using namespace std;

#define all(x) x.begin(), x.end()
#define srtl(x) sort(all(x))
#define srtg(x) sort((x).begin(),(x).end(),greater<>())
#define pb push_back
#define fr(n) for(int i=0;i<n;i++)
#define cint const int
#define int long long

cint N = 200005;
vector<int> tree(2 * N, -1); // hojas en [N, 2N), valores = índices de p (0-based) o -1

void up(int p, int v){ // p = posición comprimida (1..c), v = índice en p (0-based) o -1
    p += N;
    tree[p] = v;
    p /= 2;
    while(p >= 1){
        tree[p] = max(tree[2*p], tree[2*p+1]);
        p /= 2;
    }
}

int qr(int l, int r){ // devuelve mayor índice almacenado en [l, r] (ambos inclusive)
    l += N; r += N;
    int res = -1;
    while(l <= r){
        if(l & 1) res = max(res, tree[l++]);
        if(!(r & 1)) res = max(res, tree[r--]);
        l /= 2; r /= 2;
    }
    return res;
}

int32_t main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n,m;
    if(!(cin>>n>>m)) return 0;

    vector<pair<int,int>> v(n);
    for(int i=0;i<n;i++){
        int x,y; cin>>x>>y;
        v[i] = {y,x};
    }
    srtg(v);
    vector<int> a;
    for(int i=0;i<n;i++) a.pb(v[i].second);

    vector<int> p(m);
    for(int i=0;i<m;i++) cin>>p[i];

    // compresión
    vector<int> aa = a;
    for(int x: p) aa.pb(x);
    srtl(aa);
    aa.erase(unique(all(aa)), aa.end());
    int c = (int)aa.size(); // número de valores distintos

    // mapa por búsqueda binaria (más seguro que map con 0)
    auto getComp = [&](int x){
        return (int)(lower_bound(all(aa), x) - aa.begin()) + 1; // 1..c
    };

    for(int &x: a) x = getComp(x);
    for(int &x: p) x = getComp(x);

    // ordenar p en orden descendente pero necesitamos conservar índices
    vector<pair<int,int>> pp;
    for(int i=0;i<m;i++) pp.push_back({p[i], i});
    srtg(pp); // por valor comprimido descendente

    // reconstruir p_valores ordenados y su índice original
    vector<int> p_val(m);
    for(int i=0;i<m;i++) p_val[i] = pp[i].first;

    // limpiar árbol (usar -1)
    fill(tree.begin(), tree.end(), -1);

    int res = 0;
    // recorremos a (ya ordenado por y desc) y buscamos en el árbol el mejor índice q
    for(int i=0;i<n && res < m;i++){
        int ai = a[i]; // valor comprimido
        int q = qr(ai, c); // devuelve índice en p_val (0-based) o -1
        if(q != -1 && p_val[q] >= ai){
            // guardamos el índice q en la hoja correspondiente a ai
            up(ai, q);
            res = max(res, q + 1); // q+1 es longitud en términos de cantidad de p usados
        }
    }

    cout << res << "\n";
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...