Submission #1322115

#TimeUsernameProblemLanguageResultExecution timeMemory
1322115huynqtrapezoid (balkan11_trapezoid)C++20
12 / 100
119 ms22548 KiB
#include <bits/stdc++.h>
using namespace std;

static const int MOD = 30013;
struct Trap { long long a,b,c,d; };

struct Node {
    int val, cnt;
};

Node merge(Node x, Node y) {
    if (x.val > y.val) return x;
    if (y.val > x.val) return y;
    return {x.val, (x.cnt + y.cnt) % MOD};
}

vector<Node> st;
int SZ;

void update(int p, Node v) {
    for (st[p += SZ] = merge(st[p], v); p > 1; p >>= 1)
        st[p>>1] = merge(st[p], st[p^1]);
}

Node query(int l, int r) {
    Node res = {0,0};
    for (l += SZ, r += SZ; l <= r; l >>= 1, r >>= 1) {
        if (l & 1) res = merge(res, st[l++]);
        if (!(r & 1)) res = merge(res, st[r--]);
    }
    return res;
}

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

    int n; 
    cin >> n;
    vector<Trap> t(n);
    vector<long long> up, down;

    for (auto &x : t) {
        cin >> x.a >> x.b >> x.c >> x.d;
        up.push_back(x.a); up.push_back(x.b);
        down.push_back(x.c); down.push_back(x.d);
    }

    sort(up.begin(), up.end());
    up.erase(unique(up.begin(), up.end()), up.end());
    sort(down.begin(), down.end());
    down.erase(unique(down.begin(), down.end()), down.end());

    for (auto &x : t) {
        x.a = lower_bound(up.begin(), up.end(), x.a) - up.begin();
        x.b = lower_bound(up.begin(), up.end(), x.b) - up.begin();
        x.c = lower_bound(down.begin(), down.end(), x.c) - down.begin();
        x.d = lower_bound(down.begin(), down.end(), x.d) - down.begin();
    }

    int X = up.size(), Y = down.size();
    vector<vector<pair<int,int>>> ev(X);
    for (int i = 0; i < n; i++) {
        ev[t[i].a].push_back({0, i}); // start
        ev[t[i].b].push_back({1, i}); // end
    }

    for (auto &v : ev) sort(v.begin(), v.end());

    SZ = 1;
    while (SZ < Y) SZ <<= 1;
    st.assign(2 * SZ, {0,0});

    vector<int> dp(n), ways(n);

    for (int i = 0; i < X; i++) {
        for (auto [type, id] : ev[i]) {
            if (type == 0) {
                Node best = (t[id].c > 0) ? query(0, t[id].c - 1) : Node{0,0};
                dp[id] = best.val + 1;
                ways[id] = best.cnt ? best.cnt : 1;
            } else {
                update(t[id].d, {dp[id], ways[id]});
            }
        }
    }

    Node ans = {0,0};
    for (int i = 0; i < n; i++)
        ans = merge(ans, {dp[i], ways[i]});

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