#include <bits/stdc++.h>
using namespace std;
using i = int;
const i MOD = 30013;
struct Trap { i a, b, c, d; };
struct Seg { i mx, cnt; Seg(i m = 0, i c = 0): mx(m), cnt(c) {} };
Seg mergeSeg(const Seg &x, const Seg &y) {
if (x.mx > y.mx) return x;
if (y.mx > x.mx) return y;
if (x.mx == 0) return Seg(0, 1);
return Seg(x.mx, (x.cnt + y.cnt) % MOD);
}
struct ST {
i n; vector<Seg> t;
ST(i m): n(m), t(4*m+4, Seg(0,1)) {}
Seg queryRec(i p, i l, i r, i ql, i qr) {
if (r < ql || l > qr) return Seg(0,1);
if (ql <= l && r <= qr) return t[p];
i m = (l + r) >> 1;
return mergeSeg(
queryRec(p<<1, l, m, ql, qr),
queryRec(p<<1|1, m+1, r, ql, qr)
);
}
Seg query(i l, i r) { return l > r ? Seg(0,1) : queryRec(1,1,n,l,r); }
void updateRec(i p, i l, i r, i pos, const Seg &v) {
if (l == r) { t[p] = mergeSeg(t[p], v); return; }
i m = (l + r) >> 1;
if (pos <= m) updateRec(p<<1, l, m, pos, v);
else updateRec(p<<1|1, m+1, r, pos, v);
t[p] = mergeSeg(t[p<<1], t[p<<1|1]);
}
void update(i pos, const Seg &v) { updateRec(1,1,n,pos,v); }
};
struct BIT {
i n; vector<i> f;
BIT(i m): n(m), f(m+1,0) {}
void add(i pos, i v) {
for (; pos <= n; pos += pos & -pos)
f[pos] = (f[pos] + v) % MOD;
}
i sum(i pos) {
i s = 0;
for (; pos > 0; pos -= pos & -pos)
s = (s + f[pos]) % MOD;
return s;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
i N; cin >> N;
vector<Trap> A(N);
vector<i> C; C.reserve(4*N);
for (i idx = 0; idx < N; idx++) {
cin >> A[idx].a >> A[idx].b >> A[idx].c >> A[idx].d;
C.push_back(A[idx].a);
C.push_back(A[idx].b);
C.push_back(A[idx].c);
C.push_back(A[idx].d);
}
sort(C.begin(), C.end());
C.erase(unique(C.begin(), C.end()), C.end());
auto id = [&](i v){ return (i)(lower_bound(C.begin(), C.end(), v) - C.begin() + 1); };
i M = C.size();
for (auto &t : A) {
t.a = id(t.a);
t.b = id(t.b);
t.c = id(t.c);
t.d = id(t.d);
}
sort(A.begin(), A.end(), [](const Trap &x, const Trap &y){
return x.a != y.a ? x.a < y.a : x.b < y.b;
});
ST stTop(M), stBot(M);
vector<Seg> dp(N);
for (i idx = 0; idx < N; idx++) {
Seg leftBest = stTop.query(1, A[idx].a - 1);
Seg downBest = stBot.query(1, A[idx].c - 1);
Seg cur = mergeSeg(leftBest, downBest);
dp[idx] = Seg(cur.mx + 1, cur.cnt);
stTop.update(A[idx].b, dp[idx]);
stBot.update(A[idx].d, dp[idx]);
}
i K = 0;
for (auto &s : dp) K = max(K, s.mx);
vector<vector<i>> by(K+1);
for (i idx = 0; idx < N; idx++) by[dp[idx].mx].push_back(idx);
vector<i> cnt2(N);
for (i k = 1; k < K; k++) {
BIT bit(M);
for (i idx : by[k]) bit.add(A[idx].d, dp[idx].cnt);
for (i idx : by[k+1]) cnt2[idx] = bit.sum(A[idx].c - 1);
for (i idx : by[k+1]) dp[idx].cnt = cnt2[idx];
}
i total = 0;
for (i idx : by[K]) total = (total + dp[idx].cnt) % MOD;
cout << K << " " << total;
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |