萌新求助李超线段树模板

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

NightTide @ 2022-09-29 20:13:20

RT,sub 2 全 RE,求助

#include<bits/stdc++.h>
#define eps 1e-6
#define MAXL 40000
#define lson now << 1
#define rson now << 1 | 1
using namespace std;
struct seg{
    double k, b;
    int id;
    double val(double x){ return k * x + b; }
    seg(double _k = 0, double _b = 0, int _id = 0){ k = _k, b = _b, id = _id; };
};
struct node{
    int l, r;
    bool vis, has_seg;
    seg s;
};
node tree[MAXL << 4];
int n, ans = -1, cnt;
/*
    0  ——> x = y
    1  ——> x > y
    -1 ——> x < y
*/
int cmp(double x, double y){ return fabs(x - y) <= eps ? 0 : (x - y) < 0 ? -1 : 1; }
double cross(seg x, seg y){ return (y.b - x.b) / (x.k - y.k); };
void build(int now, int l, int r){
    tree[now].l = l; tree[now].r = r;
    tree[now].vis = tree[now].has_seg = false;
    if(tree[now].l == tree[now].r) return ;
    int mid = (l + r) >> 1;
    build(lson, l, mid); build(rson, mid + 1, r);
}
void update(int now, int l, int r, seg s){
    tree[now].vis = true;
    if(tree[now].l == l && tree[now].r == r){
        if(tree[now].has_seg == false){
            tree[now].has_seg = true;
            tree[now].s = s;
            return ;
        }
        if(cmp(tree[now].s.val(tree[now].l), s.val(tree[now].l)) >= 0 && cmp(tree[now].s.val(tree[now].r), s.val(tree[now].r)) >= 0) return ;
        if(cmp(tree[now].s.val(tree[now].l), s.val(tree[now].l)) < 0 && cmp(tree[now].s.val(tree[now].r), s.val(tree[now].r)) < 0){ tree[now].s = s; return ; }
        int mid = (tree[now].l + tree[now].r) >> 1;
        if(cmp(cross(tree[now].s, s), mid) <= 0){
            if(s.k < tree[now].s.k) update(lson, l, mid, s);
            else update(lson, l, mid, tree[now].s);
            tree[now].s = s;
        }else{
            if(s.k > tree[now].s.k) update(rson, mid + 1, r, s);
            else update(rson, mid + 1, r, tree[now].s);
            tree[now].s = s;
        }
        return ;
    }
    int mid = (tree[now].l + tree[now].r) >> 1;
    if(r <= mid) update(lson, l, r, s);
    else if(l > mid) update(rson, l, r, s);
    else update(lson, l, mid, s), update(rson, mid + 1, r, s);
}
seg query(int now, int x){
    // printf("[%d, %d], y = %lgx + (%lg)\n",tree[now].l,tree[now].r,tree[now].s.k,tree[now].s.b);
    if(tree[now].l == x && tree[now].r == x){
        return tree[now].s;
    }
    seg res = (seg){0, 0, 0};
    int mid = (tree[now].l + tree[now].r) >> 1;
    if(x <= mid) res = query(lson, x);
    else res = query(rson, x);
    if(cmp(tree[now].s.val(x), res.val(x)) >= 0) res = tree[now].s;
    return res;
}
int main(){
    scanf("%d",&n);
    build(1, 1, 39990);
    update(1, 1, 39990, (seg){0 ,0 ,0});
    for(int i = 1; i <= n; i++){
        int op, x1, y1, x2, y2, p;
        scanf("%d",&op);
        if(op == 1){
            scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
            if(x1 > x2) swap(x1, x2), swap(y1, y2);
            x1 = (x1 + ans + 39989) % 39989 + 1; y1 = (y1 + ans + 39989) % 39989 + 1;
            x2 = (x2 + ans + 39989) % 39989 + 1; y2 = (y2 + ans + 39989) % 39989 + 1;
            double k = 1.0 * (y2 - y1) / (x2 - x1), b = 1.0 * (y1 - y2) * (-x1) / (x1 - x2) + y1;
            if(x1 == x2) k = 0, b = max(y1, y2);
            seg s = (seg){k, b, ++cnt};
            update(1, x1, x2, s);
        }else{
            scanf("%d",&p);
            p = (p + ans + 39989) % 39989 + 1;
            seg res = query(1, p);
            // printf("y = %lgx + %lg\n",res.k,res.b);
            ans = res.id;
            printf("%d\n",ans);
            ans--;
        }
    }
    return 0;
}

|