代码调了2h+了,还是没过

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

EastIsRed @ 2022-08-10 17:53:05

#include<bits/stdc++.h>
using namespace std;
const int modx=39989;
const int mody=1000000000;
const double xdc=1e-9;
int n,last,tot;
struct line{
    double k,b;
}ln[1000086];
struct node{
    int l,r,val;
}tr[2600086];
inline double getnum(int no,int x)
{
    return ln[no].k*x+ln[no].b;
}
inline int doucmp(double a,double b)
{
    if(a-b>xdc)
        return 1;
    if(b-a>xdc)
        return -1;
    return 0;
}
void build(int now,int l,int r)
{
    tr[now].l=l;
    tr[now].r=r;
    tr[now].val=0;
    if(l!=r)
    {
        int mid=(l+r)>>1;
        build(now<<1,l,mid);
        build(now<<1|1,mid+1,r);
    }
}
void adline(int x1,int y1,int x2,int y2)
{
    tot++;
    if(x1==x2)
        ln[tot].k=0,ln[tot].b=max(y2,y1);
    else ln[tot].k=1.0*(y2-y1)/(x2-x1),ln[tot].b=y1-ln[tot].k*x1;
}
void ful_change(int now,int line_no)
{
    int mid=(tr[now].l+tr[now].r)>>1;
    if(doucmp(getnum(line_no,mid),getnum(tr[now].val,mid)==1))
        line_no^=tr[now].val,tr[now].val^=line_no,line_no^=tr[now].val;
    int resl=doucmp(getnum(line_no,tr[now].l),getnum(tr[now].val,tr[now].l));
    int resr=doucmp(getnum(line_no,tr[now].r),getnum(tr[now].val,tr[now].r));
    if(resl==1||(!resl&&line_no<tr[now].val))
        ful_change(now<<1,line_no);
    if(resr==1||(!resr&&line_no<tr[now].val))
        ful_change(now<<1|1,line_no);
}
void change(int now,int l,int r,int line_no)
{
    if(l<=tr[now].l&&tr[now].r<=r)
    {
        ful_change(now,line_no);
        return;
    }
    int mid=(tr[now].l+tr[now].r)>>1;
    if(l<=mid)
        change(now<<1,l,r,line_no);
    if(mid<r)
        change(now<<1|1,l,r,line_no);
}
pair<double,int> pmax(pair<double,int> a,pair<double,int> b)
{
    int flag=doucmp(a.first,b.first);
    if(flag==1)
        return a;
    if(flag==-1)
        return b;
    return a.second<b.second?a:b;
}
pair<double,int> getans(int now,int pos)
{
    if(pos<tr[now].l||tr[now].r<pos)
        return make_pair(0,0);
    int mid=(tr[now].l+tr[now].r)>>1;
    double ans=getnum(tr[now].val,pos);
    if(tr[now].l==tr[now].r)
        return make_pair(ans,tr[now].val);
    return pmax(make_pair(ans,tr[now].val),pmax(getans(now<<1,pos),getans(now<<1|1,pos)));
}
int main()
{
    scanf("%d",&n);
    build(1,1,40000);
    while(n--)
    {
        int op,x1,y1,x2,y2;
        scanf("%d%d",&op,&x1);
        x1=(x1+last-1+modx)%modx+1;
        if(op==1)
        {
            scanf("%d%d%d",&y1,&x2,&y2);
            x2=(x2+last-1+modx)%modx+1;
            y1=((long long)y1+last-1+mody)%mody+1;
            y2=((long long)y2+last-1+mody)%mody+1;
            if(x1>x2)
                x1^=x2,x2^=x1,x1^=x2,y1^=y2,y2^=y1,y1^=y2;
            adline(x1,y1,x2,y2);
            change(1,x1,x2,tot);
        }
        else printf("%d\n",last=getans(1,x1).second);
    }
    return 0;
}

|