| 比赛 |
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;
}