求助,关于线段树指针为空

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

Accoty_AM @ 2019-09-18 08:11:05

如题,我在建好线段树后,正常询问,为什么还会遇到空指针???

看modify函数,不加注释部分会re

十分感谢,嗝。。

#include<bits/stdc++.h>
using namespace std;
#define rg register
inline int read(){
    rg char ch=getchar();
    rg int x=0,f=0;
    while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return f?-x:x;
}
struct node{
    int l,r,id;
    node *ls,*rs;
    node(int l,int r,int _id,node *ls,node *rs):l(l),r(r),id(_id),ls(ls),rs(rs){}
}*root;
node *build(int l,int r){
    if(l==r) return new node(l,r,0,NULL,NULL);
    return new node(l,r,0,build(l,l+r>>1),build((l+r>>1)+1,r));
}
#define A 39989
#define B 1000000000
#define N 100010
#define eps 1e-8
int ans,now,n,cnt;
double k[N],b[N],maxnum;
int opt,x,y,xx,yy;
inline double find(int id,int x){
    return k[id]*x+b[id];
}
inline double calc(int x,int y){
    return (b[y]-b[x])/(k[x]-k[y]);
}
inline void check(int id){
    double res=find(id,now);
    if(res>maxnum) maxnum=res,ans=id;
    else if(fabs(res-maxnum)<eps) ans=min(ans,id);
}
void modify(int l,int r,int id,node *p){
    //if(!p) return;
    if(l==p->l&&r==p->r){
        if(!p->id) return (void)(p->id=id);
        if(find(p->id,l)>find(id,l)+eps&&find(p->id,r)>find(id,r)+eps) return ;
        if(find(p->id,l)+eps<find(id,l)&&find(p->id,r)+eps<find(id,r)) return (void)(p->id=id);
        if(fabs(find(p->id,l)-find(id,l))<eps&&fabs(find(p->id,r)-find(id,r))<eps) return (void)(p->id=min(p->id,id));
        int mid=(l+r)>>1;
        double pos=calc(id,p->id);
        if(fabs(l-pos)<eps){
            if(find(id,r)<find(p->id,r)) return;
            modify(l,mid,p->id,p->ls);p->id=id;
            return;
        }
        if(fabs(r-pos)<eps){
            if(find(id,l)<find(p->id,l)) return;
            modify(mid+1,r,p->id,p->rs);p->id=id;
            return;
        }
        if(pos<=mid){
            if(find(p->id,l)>find(id,l)) modify(l,mid,p->id,p->ls),p->id=id;
            else modify(l,mid,id,p->ls);
        }else{
            if(find(p->id,r)>find(id,r)) modify(mid+1,r,p->id,p->rs),p->id=id;
            else modify(mid+1,r,id,p->rs);
        }
        return;
    }
    int mid=(p->l+p->r)>>1;
    if(l>mid) return modify(l,r,id,p->rs);
    if(r<=mid) return modify(l,r,id,p->ls);
    modify(l,mid,id,p->ls),modify(mid+1,r,id,p->rs);
}
void ask(int &to,node *p){
    if(p->id) check(p->id);
    if(p->l==p->r) return;
    int mid=(p->l+p->r)>>1;
    if(to<=mid) return ask(to,p->ls);
    ask(to,p->rs);
}
int main(){
    n=read();
    root=build(1,40000);
    while(n--){
        opt=read();
        if(opt){
            x=(read()+ans-1)%A+1,y=(read()+ans-1)%B+1;
            xx=(read()+ans-1)%A+1,yy=(read()+ans-1)%B+1;
            k[++cnt]=(double)(y-yy)/(x-xx);
            b[cnt]=y-x*k[cnt];
            modify(min(x,xx),max(x,xx),cnt,root);
        }else{
            now=(read()+ans-1)%A+1;
            ans=maxnum=0;
            ask(now,root);
            printf("%d\n",ans);
        }
    }
    return 0;
}

by EndSaH @ 2019-09-18 08:24:03

不知道 RE 是什么原因,我一般习惯这样写:

struct Node
{
    void* operator new(size_t __size)
    {
        static char __buf[int(1e8)], __ptr = __buf;
        return (__ptr += __size) - __size;
    }
};

void Build(int, int, Node*&);

by Accoty_AM @ 2019-09-18 08:29:07

@EndSaH 非常感谢,我还是希望知道为什么我已经把树提前建好了,还会访问到空指针


by Ametsuji_akiya @ 2019-09-24 08:51:33

指针选手orz


|