比赛 26暑假集训模拟赛1 评测结果 AAAAAAAAAA
题目名称 光线追踪 最终得分 100
用户昵称 RpUtl 运行时间 1.540 s
代码语言 C++ 内存使用 11.98 MiB
提交时间 2026-06-29 10:14:53
显示代码纯文本
#include <bits/stdc++.h>
#define pii pair<int,int>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 4e5 + 10; 
const int inf = 1e9 + 7;
int q, o[N], nx, ny;
ll x[N], y[N], X[N], Y[N];
struct Point{ 
    Point() {}
    Point(int x,int y):x(x),y(y) {}
    ll x, y; 
};
vector<Point>bx, by, _bx, _by;
ll Cross(Point a, Point b) { 
	return a.x * b.y - a.y * b.x;
}
// < 0: a 在 b 的顺时针
// = 0: a,b 共线
// > 0: a 在 b 的逆时针 
bool cmp(Point a, Point b) {
    return Cross(a, b) > 0; 
}
struct sgt{
    pii tag[N << 2];
    #define ls (p << 1)
    #define rs (p << 1 | 1)
    void build(int p, int l, int r) {
        tag[p] = mp(inf, 0);
        if (l == r) return;
        int mid = (l + r) >> 1;
        build(ls, l, mid);
        build(rs, mid + 1, r);
        return;
    }
    void upd(int p, int l, int r, int L, int R, pii v) {
        if (L <= l && r <= R) {
            tag[p] = min(tag[p], v);
        } else {
            int mid = (l + r) >> 1;
            if (L <= mid) upd(ls, l, mid, L, R, v);
            if (R > mid) upd(rs, mid + 1, r, L, R, v); 
        }
    }
    pii ask(int p, int l, int r, int x) {
        if (l == r) return tag[p];
        int mid = (l + r) >> 1;
        if (x <= mid) {
            return min(tag[p], ask(ls, l, mid, x));
        } else {
            return min(tag[p], ask(rs, mid + 1, r, x)); 
        }
    } 
}tx, ty;
int found(Point u, int type) {
    int L, R, mid; Point tmp;
    if (type == 0) L = 0, R = bx.size() - 1;
    if (type == 1) L = 0, R = by.size() - 1;
    while (L < R) {
        mid = (L + R + 1) >> 1;
        tmp = (type ? by[mid] : bx[mid]);
        if (Cross(tmp, u) >= 0) L = mid;
        else R = mid - 1;
    }
    return R + 1;
}
int calc(int i, int u, int v) {
    if (!u || !v) return u + v;
    if (x[i] == 0) return u;
    if (y[i] == 0) return v;
    if (x[i] * y[u] == x[v] * y[i]) return max(u, v);
    else return (x[i] * y[u] > x[v] * y[i]) ? v : u;
}
int main(){ 
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    freopen("raytracing.in", "r", stdin);
    freopen("raytracing.out", "w", stdout);
    cin >> q;
    for (int i = 1; i <= q; i++) {
        cin >> o[i];
        if (o[i] == 1) {
            cin >> x[i] >> y[i] >> X[i] >> Y[i];
            _bx.push_back(Point(x[i], y[i]));
            _bx.push_back(Point(X[i], y[i]));
            _by.push_back(Point(x[i], y[i]));
            _by.push_back(Point(x[i], Y[i]));
        } else {
            cin >> x[i] >> y[i];
            _bx.push_back(Point(x[i], y[i]));
            _by.push_back(Point(x[i], y[i]));
        }
    }
    sort(_bx.begin(), _bx.end(), cmp);
    for (auto v : _bx) {
        if (!bx.size() || Cross(bx.back(), v) != 0) {
            bx.push_back(v);
        }
    }
    sort(_by.begin(), _by.end(), cmp);
    for (auto v : _by) {
        if (!by.size() || Cross(by.back(), v) != 0) {
            by.push_back(v);
        }
    }
    nx = bx.size(), ny= by.size();
    tx.build(1, 1, nx);
    ty.build(1, 1, ny);
    for (int i = 1; i <= q; i++) {
        if (o[i] == 1) {
            int lx = found(Point(X[i], y[i]), 0), rx = found(Point(x[i], y[i]), 0);
            tx.upd(1, 1, nx, lx, rx, mp(y[i], -i));
            int ly = found(Point(x[i], y[i]), 1), ry = found(Point(x[i], Y[i]), 1);
            ty.upd(1, 1, ny, ly, ry, mp(x[i], -i));
             
        } else {
            int px = found(Point(x[i], y[i]), 0);
            int ansx = -tx.ask(1, 1, nx, px).second;
            int py = found(Point(x[i], y[i]), 1);
            int ansy = -ty.ask(1, 1, ny, py).second;
            cout << calc(i, ansx, ansy) << '\n';
        }
    }
    return 0;
}