답안 #681937

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
681937 2023-01-14T22:40:13 Z badont 사다리꼴 (balkan11_trapezoid) C++17
72 / 100
185 ms 65056 KB
#include<bits/stdc++.h>
using namespace std;

void dbg_out() { cout << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << H; dbg_out(T...); }

#ifdef LOCAL
#define debug(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define debug(...) "zzz"
#endif

using LL = long long;
using LD = long double;
using pii = pair<LL,LL>;

#define FOR(i, n) for(int i = 1; i<=n; i++)
#define F0R(i, n) for(int i = 0; i<n; i++)
#define all(x) x.begin(), x.end()
#define mp make_pair
#define pb push_back
#define f first
#define s second

template<typename T, typename = void> struct is_iterable : false_type {};
template<typename T> struct is_iterable<T, void_t<decltype(begin(declval<T>())),decltype(end(declval<T>()))>> : true_type {};
template<typename T> typename enable_if<is_iterable<T>::value&&!is_same<T, string>::value,ostream&>::type operator<<(ostream &cout, T const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename T> typename enable_if<is_iterable<T>::value&&!is_same<T, string>::value,ostream&>::type operator<<(ostream &cout, T const &v) {
	cout << "["; 
	for (auto it = v.begin(); it != v.end();) {
		cout << *it;
		if (++it != v.end()) cout << ", ";
	}
	return cout << "]";
}

//var 
LL T;

const int INF = 1e9;
const LL MOD = 30013;
struct mint {
    int x;
    mint() : x(0) {}
    template <class T> mint(T value) : x(value % MOD) { if (x < 0) x += MOD; }
    mint & operator+=(const mint &oth) { x += oth.x; if (x >= MOD) x -= MOD; return *this; }
    mint & operator-=(const mint &oth) { x -= oth.x; if (x < 0) x += MOD; return *this; }
    mint & operator*=(const mint &oth) { x = (long long) x * oth.x % MOD; return *this; }
    friend mint operator+(mint l, const mint &r) { return l += r; }
    friend mint operator-(mint l, const mint &r) { return l -= r; }
    friend mint operator*(mint l, const mint &r) { return l *= r; }
    mint & operator--() { if (--x == -1) x = MOD - 1; return *this; }
    mint & operator++() { if (++x == MOD) x = 0; return *this; }
    mint operator--(int) { mint temp = *this; --*this; return temp; }
    mint operator++(int) { mint temp = *this; ++*this; return temp; }
    mint operator-() const { return 0 - *this; }
    mint operator+() const { return *this; }
    friend bool operator==(const mint &l, const mint &r) { return l.x == r.x; }
    friend bool operator!=(const mint &l, const mint &r) { return l.x != r.x; }
    friend ostream & operator<<(ostream &out, const mint &a) { return out << a.x; }
    mint pow(long long e = MOD - 2) const {
        mint ans = 1, b = *this;
        while (e > 0) {
            if (e % 2 == 1) {
                ans *= b;
            }
            b *= b;
            e /= 2;
        }
        return ans;
    }
};

struct Info {
	int dp;
	mint ways;
	Info(int dp, mint ways) : dp(dp), ways(ways) {}
	Info(int dp) : dp(dp), ways(0) {}
};

Info max(const Info& a, const Info& b) {
	if (a.dp > b.dp) { return a; }
	if (b.dp > a.dp) { return b; }
	return Info(a.dp, a.ways + b.ways);
};
 
template <typename T, int SZ>
struct PST {
    struct Node {
        T val;
        int c[2];
        Node() : val(INF, 0) {
           
            c[0] = c[1] = 0;
        }
    };
    static const int LIM = 3.1e6;
    Node d[LIM];
    int nxt = 0;
    int copy(int t) { d[nxt] = d[t]; return nxt++; }
    T comb(const T& a, const T& b) { return max(a, b); }
    void pull(int c) { d[c].val = comb(d[d[c].c[0]].val, d[d[c].c[1]].val); }
    T query(int lo, int hi, int t, int l, int r) {
        if (lo >= r || hi <= l) return T(-INF, 0);
        if (lo <= l && r <= hi) return d[t].val;
        int m = (l + r) / 2;
        T lef = query(lo, hi, d[t].c[0], l, m);
        T rig = query(lo, hi, d[t].c[1], m, r);
        return comb(lef, rig);
    }
    int upd(int i, const T& v, int t, int l, int r) {
        int x = copy(t);
        if (r - l == 1) {
            d[x].val = max(d[x].val, v);
            return x;
        }
        int m = (l + r) / 2;
        if (i < m) {
            d[x].c[0] = upd(i, v, d[x].c[0], l, m);
        }else{
            d[x].c[1] = upd(i, v, d[x].c[1], m, r);
        }
        pull(x);
        return x;
    }
    int build(const vector<T>& a, int l, int r) {
        int c = nxt++;
        if (r - l == 1) {
            if (l < (int)a.size()) d[c].val = a[l];
            return c;
        }
        int m = (l + r) / 2;
        d[c].c[0] = build(a, l, m);
        d[c].c[1] = build(a, m, r);
        pull(c);
        return c;
    }
    vector<int> rts;
    void update_time(int i, const T& v) {
		//debug(rts);
        rts.pb(upd(i, v, rts.back(), 0, SZ));
    }
    void build(const vector<T>& a) {
        rts.pb(build(a, 0, SZ));
    }
    T query_time(int ti, int lo, int hi) {
        return query(lo, hi, rts[ti], 0, SZ);
    }
};
PST<Info, 1 << 17> pst;

void solve() {
	int n;
	cin >> n;

	vector<array<int, 4>> a(n);
	for (auto& [x, y, z, d] : a)
		cin >> x >> y >> z >> d;

	vector<LL> a_ricky, b_ricky;
	for (auto [x, y, z, d] : a) {
		a_ricky.pb(x);
		a_ricky.pb(y);
		b_ricky.pb(z);
		b_ricky.pb(d);
	}

	sort(all(a_ricky));
	sort(all(b_ricky));

	a_ricky.erase(unique(all(a_ricky)), a_ricky.end());
	b_ricky.erase(unique(all(b_ricky)), b_ricky.end());

	auto get_a = [&](const int& g) -> LL {
		return lower_bound(all(a_ricky), g) - a_ricky.begin() + 1;
	};
	auto get_b = [&](const int& g) -> LL {
		return lower_bound(all(b_ricky), g) - b_ricky.begin() + 1;
	};

	int A = (int)a_ricky.size();
	int B = (int)b_ricky.size();
	vector sweep(A + 1, vector<array<LL, 3>>());

	for (auto& [x, y, z, d] : a) {
		sweep[get_a(y)].pb({get_a(x), get_b(z), get_b(d)});
	}

	//debug(sweep);
	vector<Info> init(B + 1, Info(-INF, 0)); init[0] = Info(0, 1);
	pst.build(init);
	//vector<node<Info>*> roots = {(tree.build(init))};

	Info ans(-INF, 0);
	vector<int> time_of = {0};
	FOR (i, A) {
		
		for (auto& [l, x, y] : sweep[i]) {
			Info trans = pst.query_time(time_of[l - 1], 0, x);
			Info next = Info(trans.dp + 1, trans.ways);
			ans = max(ans, next);
			Info cur = pst.query_time(pst.rts.size() - 1, y, y + 1);
			if (next.dp >= cur.dp)
				pst.update_time(y, next);
		}
		time_of.pb((int)pst.rts.size() - 1);
	}

	cout << ans.dp << " " << ans.ways << "\n";
}

int main() {
	ios_base::sync_with_stdio(0); 
	cin.tie(0);

	T = 1;
	//cin >> T;
	FOR(t, T)
		solve();

	cout.flush();
	return 0;
}

 
# 결과 실행 시간 메모리 Grader output
1 Correct 24 ms 48852 KB Output is correct
2 Correct 31 ms 48836 KB Output is correct
3 Correct 25 ms 48852 KB Output is correct
4 Correct 25 ms 48916 KB Output is correct
5 Correct 25 ms 49048 KB Output is correct
6 Correct 31 ms 49296 KB Output is correct
7 Correct 28 ms 49388 KB Output is correct
8 Correct 29 ms 49704 KB Output is correct
9 Correct 39 ms 50416 KB Output is correct
10 Correct 64 ms 52060 KB Output is correct
11 Correct 62 ms 52804 KB Output is correct
12 Correct 132 ms 56744 KB Output is correct
13 Correct 128 ms 58248 KB Output is correct
14 Incorrect 142 ms 60264 KB Output isn't correct
15 Partially correct 164 ms 60964 KB Partially correct
16 Incorrect 177 ms 61724 KB Output isn't correct
17 Incorrect 166 ms 62528 KB Output isn't correct
18 Correct 155 ms 63176 KB Output is correct
19 Incorrect 174 ms 63912 KB Output isn't correct
20 Incorrect 185 ms 65056 KB Output isn't correct