李超线段树WA on sub1#7 求调

P4097 【模板】李超线段树 / [HEOI2013] Segment

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


|