Cod sursa(job #2446357)

Utilizator ArdeleanOficialAlexandru ArdeleanOficial Data 8 august 2019 00:07:16
Problema Cele mai apropiate puncte din plan Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.58 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("obstacole.in");
ofstream fout("obstacole.out");

const int N = 1e5 + 7;

int x_coord;

struct Point {
    int x;
    int y;

    void read() {
        fin >> x >> y;
    }
};


struct Sgm {
    Point a, b;

    void read() {
        fin >> a.x >> a.y >> b.x >> b.y;
    }

    void redirect() {
        if (a.x > b.x)
            swap(a, b);
    }

    double eval() const {
        if (x_coord == a.x)
            return a.y;

        return a.y + 1.0 * (x_coord - a.x) * (b.y - a.y) / (b.x - a.x);
    }

    void operator = (Point x) {
        a = b = x;
    }

    bool operator < (const Sgm &a) const {
        return eval() < a.eval();
    }
};

Point balon[N];
Sgm sgm[N];

struct SetElm {
    int a;

    SetElm (const int &x) {
        a = x;
    }

    bool operator < (const SetElm &x) const {
        return sgm[a] < sgm[x.a];
    }
};

struct Timestamp {

    ///'I' = insert segment
    ///'i' = insert segment ciudat(\) si este ciudat pentru ca cand ii dam insert aia ii este de fapt coada
    ///'D' = delete segment
    ///'d' = delete pe segment ciudat
    ///'Q' = query pe punct

    ///ordinea : D, I, Q, d, i(sigur nu e coincodenta ca sunt crescatoare in ascii)

    char type;
    int pos;
    int x;

    bool operator < (Timestamp aux) const {
        return (x == aux.x ? type < aux.type : x < aux.x);
    }

};

set < SetElm > s;

int ans[2 * N];
vector < int > adia[2 * N];
bool viz[2 * N], radacina[2 * N];
int finalx[2 * N];

vector < int > valori;

vector < Timestamp > timestamps;

void dfs(int nod) {
    for (int i : adia[nod]) {
        if (viz[i] == 0) {
            viz[i] = 1;
            finalx[i] = finalx[nod];
            dfs(i);
        }
    }
}

int main()
{
    int n, m;
    fin >> n >> m;
    for (int i = 0; i < n; ++i) {
        sgm[i].read();
        sgm[i].redirect();
    }
    for (int i = 0; i < m; ++i)
        balon[i].read();
    for (int i = 0; i < n; ++i) {
        if (sgm[i].a.y < sgm[i].b.y) {
            timestamps.push_back((Timestamp) {'I', i, sgm[i].a.x});
            timestamps.push_back((Timestamp) {'Q', i + m, sgm[i].b.x});
            ans[i + m] = sgm[i].b.y;
            finalx[i + m] = sgm[i].b.x;
            timestamps.push_back((Timestamp) {'D', i, sgm[i].b.x});
        }
        else {
            timestamps.push_back((Timestamp) {'i', i, sgm[i].a.x});
            timestamps.push_back((Timestamp) {'Q', i + m, sgm[i].a.x});
            ans[i + m] = sgm[i].a.y;
            finalx[i + m] = sgm[i].a.x;
            timestamps.push_back((Timestamp) {'d', i, sgm[i].b.x});
        }
    }
    for (int i = 0; i < m; ++i)
        timestamps.push_back((Timestamp) {'Q', i, balon[i].x}), ans[i] = balon[i].y, finalx[i] = balon[i].x;
    sort(timestamps.begin(), timestamps.end());
    for (Timestamp i : timestamps) {
        x_coord = i.x;
        if (i.type == 'Q') {
            sgm[N - 1] = (Point){x_coord, ans[i.pos]};

            auto it = s.lower_bound((SetElm){N - 1});
            if (it != s.end())
                adia[m + it->a].push_back(i.pos), radacina[i.pos] = 1;
        }
        else if (i.type == 'd' || i.type == 'D') {
            s.erase((SetElm)i.pos);
        }
        else {
            s.insert((SetElm)i.pos);
        }
    }
    for (int i = 0; i < n + m; ++i) {
        if (!radacina[i]) {
            viz[i] = 1;
            dfs(i);
        }
    }
    for (int i = 0; i < m; ++i)
        fout << finalx[i] << '\n';
    return 0;
}