Editorial for 2183: Кулька


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <cstdio>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

struct Point {
    ll x, y;

    Point() : x(0), y(0) {}

    Point(ll x, ll y) : x(x), y(y) {}
};

ll globalX;

struct Segment {
    Point p, q;
    int id;

    Segment() : id(-1) {}

    Segment(const Point &p, const Point &q, int id) : p(p), q(q), id(id) {}

    bool operator<(const Segment &s) const {
        return
            (p.y * (q.x - p.x) + (q.y - p.y) * (globalX - p.x)) * (s.q.x - s.p.x) >
            (s.p.y * (s.q.x - s.p.x) + (s.q.y - s.p.y) * (globalX - s.p.x)) * (q.x - p.x);
    }
};

int n;
vector<Segment> a;
int m;
vector<ll> b;
vector< pair<ll, pii> > e;
set<Segment> s;
vector<int> g, f;

int get(int i) {
    return (g[i] == -1 ? i : g[i] = get(g[i]));
}

int main() {
    //freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
    ios_base::sync_with_stdio(false);

    cin >> n;
    a.resize(n);
    for (int i = 0; i < n; ++i) {
        a[i].id = i;
        cin >> a[i].p.x >> a[i].p.y
                >> a[i].q.x >> a[i].q.y;
        if (a[i].p.y < a[i].q.y) {
            e.pb(mp(a[i].p.x, mp(1, i)));
            e.pb(mp(a[i].q.x, mp(4, i)));
        } else {
            e.pb(mp(a[i].p.x, mp(0, i)));
            e.pb(mp(a[i].q.x, mp(3, i)));
        }
    }
    cin >> m;
    b.resize(m);
    for (int i = 0; i < m; ++i) {
        cin >> b[i];
        e.pb(mp(b[i], mp(2, i)));
    }

    sort(e.begin(), e.end());
    g.resize(n);
    f.resize(m);
    for (int i = 0; i < (int)e.size(); ++i) {
        globalX = e[i].fi;
        int tp = e[i].se.fi;
        int id = e[i].se.se;
        if (tp == 2)
            f[id] = (s.empty() ? -1 : s.begin()->id);
        if (tp == 1 || tp == 3) {
            set<Segment>::iterator it = s.upper_bound(a[id]);
            g[id] = (it == s.end() ? -1 : it->id);
        }
        if (tp == 0 || tp == 1)
            s.insert(a[id]);
        if (tp == 3 || tp == 4)
            s.erase(a[id]);
    }

    for (int i = 0; i < m; ++i) {
        ll res = b[i];
        if (f[i] != -1) {
            int id = get(f[i]);
            if (a[id].p.y < a[id].q.y)
                res = a[id].p.x;
            else
                res = a[id].q.x;
        }
        cout << res << '\n';
    }
    return 0;
}

Коментарі

Please read the guidelines before commenting.


Ще немає коментарів.