求助李超线段树,一直查不出错

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

Starlight237 @ 2020-10-14 22:05:15

#include<bits/stdc++.h>
using namespace std;
#define reg register
#define ll long long
extern "C" {
namespace io {
#define BUFS 100000
    static char in[BUFS], *p = in, *pp = in;
#define gc() (p == pp && (pp = (p = in) + fread(in, 1, BUFS, stdin), p == pp) ? EOF : *p++)
    inline ll read() {
        reg ll x = 0; reg char ch, f = 0;
        while (!isdigit(ch = gc())) f |= ch == '-';
        while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
        return f ? -x : x;
    }
    inline char gtc() {reg char ch; while (isspace(ch = gc())); return ch;}
}}
#define rd io :: read
const int N = 100001;
double k[N], b[N];
int n, ptr, seg[N << 2];
inline double calc(int i, int x) {return k[i] * x + b[i];}
inline int segmax(int i, int j, int x) {return calc(i, x) < calc(j, x) ? j : i;}
void ins(int cur, int l, int r, int ql, int qr, int id) {
    int mid = l + r >> 1;
    if (l == r) {seg[cur] = segmax(seg[cur], id, l); return ;}
    if (ql <= l && r <= qr) {
        if (!seg[cur]) {seg[cur] = id; return ;}
        double y1 = calc(seg[cur], mid), y2 = calc(id, mid);
        k[seg[cur]] < k[id] ?
            y1 <= y2 ? seg[cur << 1 | 1] = id, ins(cur << 1, l, mid, ql, qr, id) : ins(cur << 1 | 1, mid + 1, r, ql, qr, id)
        : k[seg[cur]] > k[id] ?
            y1 <= y2 ? seg[cur << 1] = id, ins(cur << 1 | 1, mid + 1, r, ql, qr, id) : ins(cur << 1, l, mid, ql, qr, id)
        : (b[seg[cur]] < b[id] && (seg[cur] = id), void());
        return ;
    }
    ql <= mid && (ins(cur << 1, l, mid, ql, qr, id), 0),
    mid <  qr && (ins(cur << 1 | 1, mid + 1, r, ql, qr, id), 0);
}
int query(int cur, int l, int r, int x) {
    if (l == r) return seg[cur];
    int mid = l + r >> 1;
    return segmax(seg[cur], (x <= mid ? query(cur << 1, l, mid, x) : query(cur << 1 | 1, mid + 1, r, x)), x);
}
int lstans;
inline int hshrd(int mod) {return (rd() + lstans - 1) % mod + 1;}
int main() {
    freopen("1.in", "r", stdin);
    //freopen("1.out", "w", stdout);
    n = rd();
    for (reg int i = 1; i <= n; ++i) {
        int op = rd(), x, _x0, _y0, _x1, _y1;
        switch(op) {
            case 0 :
                x = hshrd(39989);
                printf("%d\n", lstans = query(1, 1, 39989, x));
                break ;
            case 1 :
                _x0 = hshrd(39989), _y0 = hshrd(1000000000), _x1 = hshrd(39989), _y1 = hshrd(1000000000);
                _x0 > _x1 && (swap(_x0, _x1), swap(_y0, _y1), 0);
                if (_x0 == _x1) {
                    ++ptr, k[ptr] = 0, b[ptr] = max(_y0, _y1);
                    ins(1, 1, 39989, _x0, _x0, ptr);
                    break ;
                }
                ++ptr, k[ptr] = (double)(_y1 - _y0) / (_x1 - _x0), b[ptr] = _y0 - k[ptr] * _x0;
                ins(1, 1, 39989, _x0, _x1, ptr);
                break ;
        }
    }
    return 0;
}

Input:

15 
1 10106 430304987 27250 648822320
1 18837 358538029 33550 405818993
1 38094 982700962 3204 179351309
1 30012 759760524 562 94814637
1 2824 2157328 38048 173808913
1 21286 529968039 52 959360396
1 31179 121080479 34756 53631878
1 30154 653155991 12746 158842361
1 35756 305957126 5641 104974068
1 2045 488011957 25641 642713627
1 5129 86061632 114 739799333
1 31837 586492057 1169 10787421
1 28329 593225093 21156 282039585
0 7217
0 5967

正确的Output:

6
6

我的Output:

10
10

by KarL05 @ 2020-10-14 23:02:22


by Karry5307 @ 2020-10-15 08:13:27

@huanghaox1212 你可以问问 @tommy0103


by tommymio @ 2020-10-15 08:25:20

这太草了/jk/jk/jk


by tommymio @ 2020-10-15 08:26:55

神奇的逗号引发的错误?不懂,感觉可读性好差/yun


by Starlight237 @ 2020-10-15 12:01:57

@Karry5307 @tommy0103 谢谢,已经调过了,线段下传的地方搞错了

@tommy0103 可读性也不差吧((,把三目、短路啥的换成ifelse然后就和您的代码没多大区别了


by tommymio @ 2020-10-15 12:31:32

@huanghaox1212 短路啥的看起来可读性确实不太好啊(


by Starlight237 @ 2020-10-15 13:17:07

@tommy0103 但是实测通常情况下这样会快一些(吧)

比如这题我是最优解(((

评测机更新后的那几位开O2的也比我慢


|