#include<cstdio>
#include<cstring>
#include<algorithm>
struct Node {
int ope;
int x[2];
int y[2];
} node[100005];
double ac[300005];
int cnt = 0;
int tree[300005 << 2][2];
int ans[300005 << 2][2];
double at(double y, double x) {
if(x == 0) return 0x7fffffff;
return y / x;
}
void add(int now, int l, int r, int al, int ar, int val, int id, int side) {
if(l == al && r == ar) {
if(tree[now][side] >= val) {
tree[now][side] = val;
ans[now][side] = id;
}
return;
}
const int MID = (l + r) >> 1;
if(ar <= MID) {
add(now << 1, l, MID, al, ar, val, id, side);
} else if(al > MID) {
add(now << 1 | 1, MID + 1, r, al, ar, val, id, side);
} else {
add(now << 1, l, MID, al, MID, val, id, side);
add(now << 1 | 1, MID + 1, r, MID + 1, ar, val, id, side);
}
return;
}
void ask(int now, int loc, int l, int r, int &ansx, int &ansy, int &xid, int &yid) {
if(tree[now][0] < ansx) {
ansx = tree[now][0];
xid = ans[now][0];
}
if(tree[now][0] == ansx) {
xid = std::max(xid, ans[now][0]);
}
if(tree[now][1] < ansy) {
ansy = tree[now][1];
yid = ans[now][1];
}
if(tree[now][1] == ansy) {
yid = std::max(yid, ans[now][1]);
}
if(l == r) return;
const int MID = (l + r) >> 1;
if(loc <= MID) {
ask(now << 1, loc, l, MID, ansx, ansy, xid, yid);
} else {
ask(now << 1 | 1, loc, MID + 1, r, ansx, ansy, xid, yid);
}
return;
}
int main() {
int open;
scanf("%d", &open);
for(int i = 1; i <= open; ++i) {
scanf("%d", &node[i].ope);
switch(node[i].ope) {
case 1: {
scanf("%d%d%d%d", &node[i].x[0], &node[i].y[0], &node[i].x[1], &node[i].y[1]);
ac[++cnt] = at(node[i].y[0], node[i].x[0]);
// printf("%lf\n", ac[cnt]);
ac[++cnt] = at(node[i].y[1], node[i].x[0]);
// printf("%lf\n", ac[cnt]);
ac[++cnt] = at(node[i].y[0], node[i].x[1]);
// printf("%lf\n", ac[cnt]);
break;
}
case 2: {
scanf("%d%d", &node[i].x[0], &node[i].y[0]);
ac[++cnt] = at(node[i].y[0], node[i].x[0]);
// printf("%lf\n", ac[cnt]);
break;
}
}
}
std::sort(ac + 1, ac + 1 + cnt);
// for(int i = 1; i <= cnt; ++i) {
// printf("%lf\n", ac[i]);
// }
memset(tree, 0x7f, sizeof(tree));
for(int i = 1; i <= open; ++i) {
switch(node[i].ope) {
case 1: {
int li = std::lower_bound(ac + 1, ac + 1 + cnt, at(node[i].y[0], node[i].x[0])) - ac;
int ri = std::lower_bound(ac + 1, ac + 1 + cnt, at(node[i].y[1], node[i].x[0])) - ac;
add(1, 1, cnt, li, ri, node[i].x[0], i, 0);
ri = li;
li = std::lower_bound(ac + 1, ac + 1 + cnt, at(node[i].y[0], node[i].x[1])) - ac;
add(1, 1, cnt, li, ri, node[i].y[0], i, 1);
break;
}
case 2: {
int x = node[i].x[0];
int y = node[i].y[0];
double k = at(y, x);
int loc = std::lower_bound(ac + 1, ac + 1 + cnt, k) - ac;
int ansx = 0x7fffffff;
int xid = 0;
int ansy = 0x7fffffff;
int yid = 0;
ask(1, loc, 1, cnt, ansx, ansy, xid, yid);
if(!xid || !yid) {
printf("%d\n", xid + yid);
} else {
if(k == 0x7fffffff) {
if(node[xid].y[0] < node[yid].y[0]) {
printf("%d\n", xid);
} else if(node[yid].y[0] < node[xid].y[0]) {
printf("%d\n", yid);
} else {
printf("%d\n", std::max(xid, yid));
}
} else if(k == 0) {
if(node[xid].x[0] < node[yid].x[0]) {
printf("%d\n", xid);
} else if(node[yid].x[0] < node[xid].x[0]) {
printf("%d\n", yid);
} else {
printf("%d\n", std::max(xid, yid));
}
} else {
if(ansx * k == ansy) {
printf("%d\n", std::max(xid, yid));
}
if(ansx * k < ansy) {
printf("%d\n", xid);
}
if(ansx * k > ansy) {
printf("%d\n", yid);
}
}
}
break;
}
}
}
return 0;
}
光线追踪
Share