求调,问题出在主函数

P6136 【模板】普通平衡树(数据加强版)

leiaxiwo @ 2024-04-18 13:51:22

从隔壁普通版过来的,我读了半要求主函数调了十几分钟还是没有正常输出,十分不解,求调。

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int root,tot;
struct splay_tree{
    int ch[2],siz,cnt,fa,val;
}tree[1000005];
inline int read(){
    int x=0;
    int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-'){
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
void update(int x){
    tree[x].siz=tree[tree[x].ch[0]].siz+tree[tree[x].ch[1]].siz+tree[x].cnt;
    return ;
}
bool get(int x){
    return x==tree[tree[x].fa].ch[1];
}
void rotate(int x)
{
    int y=tree[x].fa,z=tree[y].fa,chk=get(x);
    tree[y].ch[chk]=tree[x].ch[chk^1];
    if(tree[x].ch[chk^1])
        tree[tree[x].ch[chk^1]].fa=y;
    tree[x].ch[chk^1]=y;
    tree[y].fa=x;
    tree[x].fa=z;
    if(z)
        tree[z].ch[y==tree[z].ch[1]]=x;
    update(y);
    update(x);
    return ;
}
void splay(int x){
    for(int f=tree[x].fa;f=tree[x].fa,f;rotate(x))
        if(tree[f].fa)
            rotate(get(x)==get(f)?f:x);
    root=x;
}
void clear(int x){
    tree[x].ch[0]=tree[x].ch[1]=tree[x].fa=tree[x].val=tree[x].cnt=tree[x].siz=0;
    return ;
}
void insert(int k)
{
    if(!root)
    {
        tree[++tot].val=k;
        tree[tot].cnt++;
        root=tot;
        update(root);
        return;
    }
    int cur=root,f=0;
    while(1)
    {
        if(tree[cur].val==k)
        {
            tree[cur].cnt++;
            update(cur);
            update(f);
            splay(cur);
            break;
        }
        f=cur;
        cur=tree[f].ch[tree[f].val<k];
        if(!cur)
        {
            tree[++tot].val=k;
            tree[tot].cnt++;
            tree[tot].fa=f;
            tree[f].ch[tree[f].val<k]=tot;
            update(tot);
            update(f);
            splay(tot);
            break;
        }
    }
}
//bug on rnk
int rnk(int x){
    int res=0,cur=root;
    while(1){
        if(x<tree[cur].val)
            cur=tree[cur].ch[0];
        else{
            res+=tree[tree[cur].ch[0]].siz;
            if(x==tree[cur].val){
                splay(cur);
                return res+1;
            }
            res+=tree[cur].cnt;
            cur=tree[cur].ch[1];
        }
    }
}
int kth(int x){
    int cur=root;
    while(1){
        if(tree[cur].ch[0]&&x<=tree[tree[cur].ch[0]].siz){
            cur=tree[cur].ch[0];
        }
        else{
            x-=tree[tree[cur].ch[0]].siz+tree[cur].cnt;
            if(x<=0){
                splay(cur);
                return tree[cur].val;
            }
            cur=tree[cur].ch[1];
        }
    }
}
int pre(){
    int cur=tree[root].ch[0];
    if(!cur){
        return cur;
    }
    while(tree[cur].ch[1]){
        cur=tree[cur].ch[1];
    }
    splay(cur);
    return cur;
}
int next(){
    int cur=tree[root].ch[1];
    if(!cur){
        return cur;
    }
    while(tree[cur].ch[0]){
        cur=tree[cur].ch[0];
    }
    splay(cur);
    return cur;
}
void del(int x){
    rnk(x);
    if(tree[root].cnt>1){
        tree[root].cnt--;
        update(root);
        return ;
    }
    if(!tree[root].ch[0]&&!tree[root].ch[1]){
        clear(root);
        root=0;
        return ;
    }
    if(!tree[root].ch[0]){
        int cur=root;
        root=tree[root].ch[1];
        tree[root].fa=0;
        clear(cur);
        return ;
    }
    if(!tree[root].ch[1]){
        int cur=root;
        root=tree[root].ch[0];
        tree[root].fa=0;
        clear(cur);
        return ;
    }
    int cur=root;
    pre();
    tree[tree[cur].ch[1]].fa=root;
    tree[root].ch[1]=tree[cur].ch[1];
    clear(cur);
    update(root);
    return ;
}
int last,ans;
signed main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++){
        int x=read();
        insert(x);
    }
    for(int i=1;i<=m;i++){
        int opt=read(),x=read();
        if(opt==1){
            insert(x^last);
        }
        else if(opt==2){
            del(x^last);
        }
        else if(opt==3){
            insert(x^last);
            last=rnk(x^last);
            del(x^last);
            ans^=last;
        }
        else if(opt==4){
            insert(x^last);
            last=kth(x^last);
            del(x^last);
            ans^=last;
        }
        else if(opt==5){
            insert(x^last);
            last=tree[pre()].val;
            del(x^last);
            ans^=last;
        }
        else if(opt==6){
            insert(x^last);
            last=tree[next()].val;
            del(x^last);
            ans^=last;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

by Terrible @ 2024-04-18 14:27:09

@liverxiwo

在最前面直接先解析出 xx=read()^last,你 main() 函数里面有修改 last 之后还调用 x^last 的情形,这显然是说不过去的。

int opt=read(),x=read()^last;
        if(opt==1){
            insert(x);
        }
        else if(opt==2){
            del(x);
        }
        else if(opt==3){
            insert(x);
            last=rnk(x);
            del(x);
            ans^=last;
        }
        else if(opt==4){
            insert(x);
            last=kth(x);
            del(x);
            ans^=last;
        }
        else if(opt==5){
            insert(x);
            last=tree[pre()].val;
            del(x);
            ans^=last;
        }
        else if(opt==6){
            insert(x);
            last=tree[next()].val;
            del(x);
            ans^=last;
        }

修改了这些再交上去好像还有问题,测试点 #2 TLE 了,但是我这里跑得时间和结果上都没问题。


by Terrible @ 2024-04-18 14:39:07

测试点 #2 出问题大概是因为数组没开够,数组应该开 1100005 这么大吧。

改完还是不过。。。


by leiaxiwo @ 2024-04-19 12:37:22

@Terrible 谢谢,不过我开3000005仍然没有过,我再发一个求调蹲大佬吧。。。


|