求助,关于UB
查看原帖
求助,关于UB
104324
abruce楼主2020/8/5 11:10

本地测是对的,但到了在线IDE之后就超时,我加了一堆调试语句后发现在Splay.findx这里超时了,求大佬看一下。

#include<bits/stdc++.h>
using namespace std;
namespace io {
    inline int read() {
        int __x=0,__f=1;
        char __c=getchar();
        while(__c<'0'||__c>'9') {
            if(__c=='-')__f=-1;
            __c=getchar();
        }
        while(__c>='0'&&__c<='9') {
            __x=__x*10+__c-'0';
            __c=getchar();
        }
        return __x*__f;
    }
    char __F[200];
    inline void write(int __x) {
        if(__x==0) {
            putchar('0');
            return;
        }
        int __tmp,__cnt=0;
        if(__x>0) {
            __tmp=__x;
        } else {
            __tmp=-__x;
        }
        if(__x<0) {
            putchar('-');
        }
        while(__tmp>0) {
            __F[__cnt++]=__tmp%10+'0';
            __tmp/=10;
        }
        while(__cnt>0) {
            putchar(__F[--__cnt]);
        }
    }
}
using namespace io;
const int maxn=100005;
int n,m,a[maxn];
struct splaytree {
    int news,cnt;
    struct tree {
        int sum,f,num,siz,ln,rn;
        int ch[2];
    } t[maxn*20];
    void pushup(int x) {
        t[x].siz=t[t[x].ch[0]].siz+t[t[x].ch[1]].siz+t[x].num;
        return;
    }
    void rotate(int x,int &rot) {
        int y=t[x].f,z=t[y].f,L=(t[y].ch[0]!=x),R=L^1;
        if(y==rot) {
            rot=x;
        } else {
            t[z].ch[t[z].ch[0]!=y]=x;
        }
        t[x].f=z;
        t[y].f=x;
        t[t[x].ch[R]].f=y;
        t[y].ch[L]=t[x].ch[R];
        t[x].ch[R]=y;
        pushup(y);
        pushup(x);
    }
    void splay(int x,int &rot) {
        while(x!=rot) {
            int y=t[x].f,z=t[y].f;
            if(y!=rot) {
                if(t[y].ch[0]==x^t[z].ch[0]==y) {
                    rotate(x,rot);
                } else {
                    rotate(y,rot);
                }
            }
            rotate(x,rot);
        }
    }
    int getfront(int rot) {
        int x=t[rot].ch[0];
        while(t[x].ch[1]) {
            x=t[x].ch[1];
        }
        return x;
    }
    int getback(int rot) {
        int x=t[rot].ch[1];
        while(t[x].ch[0]) {
            x=t[x].ch[0];
        }
        return x;
    }
    void insert(int rot,int x) {
        if(t[rot].sum>x&&t[rot].ch[0]) {
            insert(t[rot].ch[0],x);
        } else if(t[rot].sum<x&&t[rot].ch[1]) {
            insert(t[rot].ch[1],x);
        } else if(t[rot].sum==x) {
            t[rot].num++;
            t[rot].siz++;
            news=rot;
        } else {
            t[rot].ch[t[rot].sum<x]=++cnt;
            t[cnt].f=rot;
            t[cnt].siz=1;
            t[cnt].num=1;
            t[cnt].sum=x;
            news=cnt;
        }
        pushup(rot);
    }
    void del(int &root,int rot,int x) {
        if(t[rot].sum>x&&t[rot].ch[0]) {
            del(root,t[rot].ch[0],x);
        } else if(t[rot].sum<x&&t[rot].ch[1]) {
            del(root,t[rot].ch[1],x);
        } else if(t[rot].sum==x) {
            t[rot].num--;
            if(!t[rot].num) {
                splay(rot,root);
                int he=getfront(root),ta=getback(root);
                splay(he,root);
                splay(ta,t[he].ch[1]);
                t[rot].f=t[rot].siz=t[rot].sum=t[ta].ch[0]=0;
                pushup(ta);
                pushup(he);
            }
        }
        pushup(rot);
    }
    int findx(int &rot,int x) {
        if(!rot)return 0;
        int u=rot;
        while(t[u].ch[(t[u].sum<x)]!=0&&t[u].sum!=x) {
            cout<<'#'<<endl;
            cout<<u<<' '<<(t[u].sum<x)<<' '<<t[u].ch[(t[u].sum<x)]<<' '<<t[u].sum<<' '<<t[t[u].ch[(t[u].sum<x)]].sum<<endl;
            u=t[u].ch[(t[u].sum<x)];
            cout<<u<<' '<<(t[u].sum<x)<<' '<<t[u].ch[(t[u].sum<x)]<<' '<<t[u].sum<<' '<<t[t[u].ch[(t[u].sum<x)]].sum<<endl;
        }
        cout<<'*';
        splay(u,rot);
        //cout<<'*';
        return t[rot].sum>=x?t[t[rot].ch[0]].siz-1:t[t[rot].ch[0]].siz+t[rot].num-1;
    }
    int findk(int rot,int k) {
        int lsiz=t[t[rot].ch[0]].siz;
        if(!rot)return INT_MAX;
        if(lsiz+t[rot].num>=k&&lsiz<k) {
            return rot;
        } else if(lsiz>=k) {
            return findk(t[rot].ch[0],k);
        } else {
            return findk(t[rot].ch[1],k-lsiz-t[rot].num);
        }
    }
    int get(int &rot,int x,int pd) {
        insert(rot,x);
        splay(news,rot);
        int ans=t[pd?getfront(rot):getback(rot)].sum;
        del(rot,rot,x);
        return ans;
    }
    void tab(int &root) {
        root=++cnt;
        t[++cnt].f=cnt-1;
        t[cnt-1].ch[0]=cnt;
        t[cnt].sum=INT_MIN+1;
        t[cnt-1].sum=INT_MAX;
        t[cnt].num=t[cnt-1].num=1;
        t[cnt].siz=1;
        t[cnt-1].siz=2;
    }
} Splay;
struct segment {
    struct tree {
        int l,r,root;
    } t[maxn*8];
    void build(int id,int l,int r) {
        t[id].l=l;
        t[id].r=r;
        Splay.tab(t[id].root);
        for(register int i=l; i<=r; i++) {
            Splay.insert(t[id].root,a[i]);
        }
        if(l==r)return;
        int mid=(l+r)/2;
        build(id*2,l,mid);
        build(id*2+1,mid+1,r);
    }
    void change(int id,int x,int y) {
        if(t[id].l>x||t[id].r<x)return;
        Splay.del(t[id].root,t[id].root,a[x]);
        Splay.insert(t[id].root,y);
        Splay.splay(Splay.news,t[id].root);
        if(t[id].l==t[id].r)return;
        change(id*2,x,y);
        change(id*2+1,x,y);
    }
    int qrank(int id,int l,int r,int k) {
        if(t[id].l>r||t[id].r<l)return 0;
        if(t[id].l>=l&&t[id].r<=r)return Splay.findx(t[id].root,k);
        return qrank(id*2,l,r,k)+qrank(id*2+1,l,r,k);
    }
    int qnum(int u,int v,int k) {
        int l=0,r=1e8,mid,ans;
        while(l<=r) {
            mid=(l+r)/2;
            //cout<<l<<' '<<r<<' '<<mid<<endl;
            if(qrank(1,u,v,mid)<k) {
                l=mid+1;
                ans=mid;
            } else {
                r=mid-1;
            }
        }
        return ans;
    }
    int qfb(int id,int l,int r,int k,int pd) {
        if(t[id].l>r||t[id].r<l)return pd?INT_MIN+1:INT_MAX;
        if(t[id].l>=l&&t[id].r<=r) {
            return Splay.get(t[id].root,k,pd);
        }
        int lc=qfb(id*2,l,r,k,pd),rc=qfb(id*2+1,l,r,k,pd);
        return pd?max(lc,rc):min(lc,rc);
    }
    void dfscout(int id) {
        cout<<t[id].l<<' '<<t[id].r<<' '<<t[id].root<<endl;
        if(t[id].l==t[id].r) {
            return;
        }
        dfscout(id*2);
        dfscout(id*2+1);
    }
} Seg;
int main() {
    int x,y,z,w;
    n=read(),m=read();
    //scanf("%d%d",&n,&m);
    for(register int i=1; i<=n; i++) {
        a[i]=read();
        //scanf("%d",&a[i]);
    }
    Seg.build(1,1,n);
//    Seg.dfscout(1);
//    puts("------");
//    for(register int i=1; i<=Splay.cnt; i++) {
//        cout<<Splay.t[i].sum<<' '<<Splay.t[i].f<<' '<<Splay.t[i].ch[0]<<' '<<Splay.t[i].ch[1]<<' '<<Splay.t[i].siz<<' '<<Splay.t[i].num<<endl;
//    }
    for(register int i=1; i<=m; i++) {
        w=read(),x=read(),y=read();
        //scanf("%d%d%d",&w,&x,&y);
        //cout<<w<<' '<<x<<' '<<y<<endl;
        switch(w) {
            case 1: {
                z=read();
                //scanf("%d",&z);
                write(Seg.qrank(1,x,y,z)+1);
                putchar('\n');
                break;
            }
            case 2: {
                z=read();
                //scanf("%d",&z);
                write(Seg.qnum(x,y,z));
                putchar('\n');
                break;
            }
            case 3: {
                Seg.change(1,x,y);
                a[x]=y;
                break;
            }
            case 4: {
                z=read();
                //scanf("%d",&z);
                write(Seg.qfb(1,x,y,z,1));
                putchar('\n');
                break;
            }
            case 5: {
                z=read();
                //scanf("%d",&z);
                write(Seg.qfb(1,x,y,z,0));
                putchar('\n');
                break;
            }
        }
    }
    return 0;
}
2020/8/5 11:10
加载中...