Splay 10分求助

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

Jairon314 @ 2021-04-08 20:38:50

写了一晚上以后就只得了十分(在普通数据的题里能过),发现了这篇讨论,于是照着解答的人的思路改了改,还是炸了/kel

有没有大佬来帮忙看看我的代码呀?码风一般请见谅

//最早的代码

#include <cstdio>
using namespace std;

#define int long long

/***************快读***************/

namespace IO {
char buf[1<<21], *p1 = buf, *p2 = buf, buf1[1<<21];
inline char gc () {return p1 == p2 && (p2 = (p1 = buf) + fread (buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}

#ifndef ONLINE_JUDGE
#endif

#define gc getchar

template<class I>
inline void read(I &x) {
    x = 0; I f = 1; char c = gc();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc(); }
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = gc(); }
    x *= f;
}

template<class I>
inline void write(I x) {
    if(x == 0) {putchar('0'); return;}
    I tmp = x > 0 ? x : -x;
    if(x < 0) putchar('-');
    int cnt = 0;
    while(tmp > 0) {
        buf1[cnt++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while(cnt > 0) putchar(buf1[--cnt]);
}

#define in(x) read(x)
#define outn(x) write(x), putchar('\n')
#define out(x) write(x), putchar(' ')

} using namespace IO;

/***************快读***************/

#define maxn 1000010

struct Splay_Fold{
    #define debug(); puts("Orz");

    struct Splay_tree{
        int son[2];
        int fa;
        int cnt;
        int size;
        int val;
    }tree[maxn];

    int tree_cnt,root;

    void Clear(int ID){
        tree[ID].son[0]=tree[ID].son[1]=0;
        tree[ID].fa=0;
        tree[ID].size=0;
        tree[ID].cnt=0;
        tree[ID].val=0;
    }

    void pushup(int ID){
        if(ID){
            tree[ID].size=tree[ID].cnt;
            if(tree[ID].son[0]){
                tree[ID].size+=tree[tree[ID].son[0]].size;
            }
            if(tree[ID].son[1]){
                tree[ID].size+=tree[tree[ID].son[1]].size;
            }
        }
    }

    bool Son(int ID){
        return tree[tree[ID].fa].son[1]==ID;
    }

    void rotate(int ID){
        int fa=tree[ID].fa;
        int gra_fa=tree[fa].fa;
        int ty_son=Son(ID);
        tree[fa].son[ty_son]=tree[ID].son[ty_son^1];
        tree[tree[ID].son[ty_son^1]].fa=fa;
        tree[ID].son[ty_son^1]=fa;
        tree[fa].fa=ID;
        tree[ID].fa=gra_fa;
        if(gra_fa){
            tree[gra_fa].son[tree[gra_fa].son[1]==fa]=ID;
        }
        pushup(fa);
        pushup(ID);
    }

    void Splay(int ID,int goal){
        for(int index;(index=tree[ID].fa)!=goal;rotate(ID)){
            if(tree[index].fa!=goal){
                if(Son(ID)==Son(index)){
                    rotate(index);
                }
                else{
                    rotate(ID);
                }
            }
        }
        if(goal==0){
            root=ID;
        }
    }

    void insert(int val){
        if(!root){
            ++tree_cnt;
            tree[tree_cnt].son[0]=tree[tree_cnt].son[1]=0;
            tree[tree_cnt].fa=0;
            tree[tree_cnt].size=tree[tree_cnt].cnt++;
            tree[tree_cnt].val=val;
            root=tree_cnt;
            return;
        }
        int index=root,fa=0;
        while(19260817){
            if(val==tree[index].val){
                ++tree[index].cnt;
                pushup(index);
                pushup(fa);
                Splay(index,0);
                return;
            }
            fa=index;
            index=tree[index].son[tree[index].val<val];
            if(!index){
                ++tree_cnt;
                tree[tree_cnt].son[0]=tree[tree_cnt].son[1]=0;
                tree[tree_cnt].size=tree[tree_cnt].cnt=1;
                tree[tree_cnt].fa=fa;
                tree[tree_cnt].val=val;
                tree[fa].son[tree[fa].val<val]=tree_cnt;
                pushup(fa);
                Splay(tree_cnt,0);
                return;
            }
        }
    }

    int NumQuery(int ID){
        int index=root;
        while(19260817){
            if(tree[index].son[0]&&tree[tree[index].son[0]].size>=ID){
                index=tree[index].son[0];
            }
            else{
                int temp=(tree[index].son[0]?tree[tree[index].son[0]].size:0)+tree[index].cnt;
                if(temp>=ID){
                    return tree[index].val;
                }
                ID-=temp;
                index=tree[index].son[1];
            }
        }
    }

    int RankQuery(int val){
        int index=root,res=0;
        while(19260817){
            if(tree[index].val>val){
                index=tree[index].son[0];
            }
            else{
                res+=(tree[index].son[0]?tree[tree[index].son[0]].size:0);
                if(tree[index].val==val){
                    Splay(index,0);
                    return res+1;
                }
                res+=tree[index].cnt;
                index=tree[index].son[1];
            }
        }
    }

    int Pre(){
        int index=tree[root].son[0];
        while(tree[index].son[1]){
            index=tree[index].son[1];
        }
        return index;
    }

    int Suf(){
        int index=tree[root].son[1];
        while(tree[index].son[0]){
            index=tree[index].son[0];
        }
        return index;
    }

    void CutOut(int val){
        int rank=RankQuery(val);
        if(tree[root].cnt>1){
            --tree[root].cnt;
            pushup(root);
            return;
        }
        if(!tree[root].son[0]&&!tree[root].son[1]){
            Clear(root);
            root=0;
            return;
        }
        if(!tree[root].son[0]){
            int old_root=root;
            root=tree[root].son[1];
            tree[root].fa=0;
            Clear(old_root);
            return;
        }
        if(!tree[root].son[1]){
            int old_root=root;
            root=tree[root].son[0];
            tree[root].fa=0;
            Clear(old_root);
            return;
        }
        int left=Pre(),old_root=root;
        Splay(left,0);
        tree[root].son[1]=tree[old_root].son[1];
        tree[tree[old_root].son[1]].fa=root;
        Clear(old_root);
        pushup(root);
    }
}splay;

int n,m;
int last;
int ans;

signed main(){
    read(n),read(m);
    for(int i=1,opt;i<=n;i++){
        read(opt);
        splay.insert(opt);
    }
    for(int i=1,opt,x;i<=m;i++){
        read(opt),read(x);
        x^=last;
        if(opt==1){
            splay.insert(x);
        }
        else if(opt==2){
            splay.CutOut(x);
        }
        else if(opt==3){
            last=(splay.RankQuery(x));
            ans^=last;
        }
        else if(opt==4){
            last=(splay.NumQuery(x));
            ans^=last;
        }
        else if(opt==5){
            splay.insert(x);
            last=(splay.tree[splay.Pre()].val);
            ans^=last;
            splay.CutOut(x);
        }
        else if(opt==6){
            splay.insert(x);
            last=(splay.tree[splay.Suf()].val);
            ans^=last;
            splay.CutOut(x);
        }
    }
    outn(ans);
    return 0;
}

by Jairon314 @ 2021-04-08 20:40:56

样例过不了(((操作3进死循环了


by Jairon314 @ 2021-04-08 20:42:10

话说这样能拿10分也在我的意料之外


by Jairon314 @ 2021-04-08 21:35:14

又学了一下,稍微一改80分惹/kk


by Jairon314 @ 2021-04-08 22:06:02

数组开小了...nt错误/kk


|