StrSeeker @ 2023-12-21 16:47:29
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mp make_pair
const int mod = 1e9 + 7;
int read () {
int x = 0, f = 1;
char ch = getchar ();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar ();
}
return x * f;
}
void write (int x) {
if (x < 0) x = -x, putchar ('-');
if (x >= 10) write (x / 10);
putchar (x % 10 + '0');
}
int quickmod (int x, int y) {
int Ans = 1;
while (y) {
if (y & 1) Ans = (Ans * x) % mod;
x = (x * x) % mod;
y >>= 1;
}
return Ans;
}
struct Line {
int fx, fy, nx, ny;
double nm;
}q[100005];
double get_ans (int x, int id) {
return 1.0 * q[id].fy + 1.0 * (q[id].ny - q[id].fy) / (q[id].nx - q[id].fx) * (x - q[id].fx);
}
int Ans = 0;
struct Seg_Tree {
struct st {
int l, r;
int p;
}t[400005];
void build (int id, int l, int r) {
t[id].l = l, t[id].r = r;
if (l == r) return ;
int mid = (l + r) / 2;
build (id << 1, l, mid);
build (id << 1 | 1, mid + 1, r);
}
void put_down (int id, int x) {
if (x == 0) return ;
if (t[id].p == 0) t[id].p = x;
else {
if (t[id].l == t[id].r) {
if ((get_ans (t[id].l, t[id].p) < get_ans (t[id].l, x)) || (get_ans (t[id].l, t[id].p) == get_ans (t[id].l, x) && t[id].p > x)) t[id].p = x;
return ;
}
int mid = (t[id].l + t[id].r) / 2;
if (q[t[id].p].nm == q[x].nm) {
if ((get_ans (mid, t[id].p) < get_ans (mid, x)) || (get_ans (mid, t[id].p) == get_ans (mid, x) && t[id].p > x)) {
t[id].p = x;
}
}
else if (q[t[id].p].nm < q[x].nm) {
if ((get_ans (mid, t[id].p) < get_ans (mid, x)) || (get_ans (mid, t[id].p) == get_ans (mid, x) && t[id].p > x)) {
put_down (id << 1, t[id].p);
t[id].p = x;
}
else {
put_down (id << 1 | 1, x);
}
}
else {
if ((get_ans (mid, t[id].p) > get_ans (mid, x)) || (get_ans (mid, t[id].p) == get_ans (mid, x) && t[id].p < x)) {
put_down (id << 1, x);
}
else {
put_down (id << 1 | 1, t[id].p);
t[id].p = x;
}
}
}
}
void push_down (int id, int x) {
if (q[x].fx <= t[id].l && t[id].r <= q[x].nx)
{
put_down (id, x);
return ;
}
int mid = (t[id].l + t[id].r) / 2;
if (q[x].fx <= mid) push_down (id << 1, x);
if (q[x].nx > mid) push_down (id << 1 | 1, x);
}
void get_h (int id, int x) {
if (Ans == 0) Ans = t[id].p;
else {
if ((get_ans (x, Ans) < get_ans (x, t[id].p)) || (get_ans (x, Ans) == get_ans (x, t[id].p) && Ans > t[id].p)) Ans = t[id].p;
}
if (t[id].l == t[id].r) return ;
int mid = (t[id].l + t[id].r) / 2;
if (x <= mid) get_h (id << 1, x);
else get_h (id << 1 | 1, x);
}
}T;
int tot = 0;
// int high[100005];
signed main ()
{
int n = read ();
T.build(1, 1, 40000);
int lst = 0;
for (int i = 1; i <= n; i++) {
int op = read ();
if (op == 1) {
tot++;
q[tot].fx = (read () + lst - 1) % 39989 + 1, q[tot].fy = (read () + lst - 1) % 1000000000 + 1;
q[tot].nx = (read () + lst - 1) % 39989 + 1, q[tot].ny = (read () + lst - 1) % 1000000000 + 1;
if (q[tot].fx != q[tot].nx) q[tot].nm = 1.0 * (q[tot].ny - q[tot].fy) / (q[tot].nx - q[tot].fx);
else q[tot].nm = 0;
if (q[tot].fx > q[tot].nx) swap (q[tot].fx, q[tot].nx), swap (q[tot].fy, q[tot].ny);
T.push_down(1, tot);
}
else {
Ans = 0;
int x = (read () + lst - 1) % 39989 + 1;
T.get_h(1, x);
printf ("%lld\n", lst = Ans);
}
}
return 0;
}
input:
3
1 1 1 1 2
1 1 1 1 3
0 1
ANSWER:
2
WROND ANSWER:
1
by StrSeeker @ 2023-12-21 16:51:13
写错了是subtask 0的#7
by GGrun @ 2024-10-03 21:29:14
对于没有斜率的线段,交点按最高点算,所以 #7 里面第一条的交点是 2 ,第二条的交点是 3