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.
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; }
Коментарі