康复训练替罪羊树58分求救
查看原帖
康复训练替罪羊树58分求救
103168
枫之都楼主2024/7/8 15:43

五年没打oi了 高中毕业赶紧来做康复训练 打了一个替罪羊树 本来代码还是比较整洁的,结果才27分 打了一堆补丁才58分 求救 谁帮我看一眼

#include<iostream>
#include<array>
#include<stack>
namespace SBTree
{
    template<typename N,size_t sz>
    class CM_Pool
    {
    public:
        N m_pool[sz];
        std::stack<size_t> m_rec;
        size_t top;
        CM_Pool()
        {
            top=0;
        }
        size_t new_node()
        {
            if(m_rec.empty())
            {
                return ++top;
            }
            else
            {
                size_t tmp=m_rec.top();
                m_rec.pop();
                return tmp;
            }
        }
        size_t delete_node(size_t n)
        {
            if(n==0)return 0;
            m_rec.push(n);
            return n;
        }
        N& operator[](size_t n)
        {
            return m_pool[n];
        }
        size_t m_null()
        {
            return 0;
        }
    };
    template<typename T,size_t sz,int AL=75>
    class SBTree
    {
        float alpha;
        class Node
        {
        public:
            T m_key;
            size_t m_ls,m_rs,m_w,m_rw,mol;
            bool del;
            Node()
            {m_ls=m_rs=m_w=m_rw=del=mol=0;}
            Node(T K)
            {
                m_key=K;
                m_ls=m_rs=m_w=m_rw=del=0;
                mol=1;
            }
            bool clear()
            {
                m_ls=m_rs=m_w=m_rw=del=mol=0;
                return 0;
            }
            bool set(T k,size_t ls=0,size_t rs=0,size_t w=1,size_t rw=1,bool b=0,size_t m=1)
            {
                m_key=k,m_ls=ls,m_rs=rs,m_w=w,m_rw=rw,del=b,mol=m;
                //std::cout<<"set:"<<k<<'\n';
                return 0;
            }
        };
        CM_Pool<Node,sz> Tree;
        size_t root;
        size_t IOT(size_t r,/*std::array<size_t>*/ Node arr[],size_t n)
        {
            if(r==0)return n;
            if(Tree[r].m_ls!=0)n=IOT(Tree[r].m_ls,arr,n);
            if(!Tree[r].del)
            {
                while(Tree[r].mol--)arr[n++]=Tree[r];
            }
            if(Tree[r].m_rs!=0)n=IOT(Tree[r].m_rs,arr,n);
            Tree[r].clear();
            Tree.delete_node(r);
            return n;
        }
        size_t Build (Node arr[],size_t first,size_t end)
        {
            if(end<first) return 0;
            size_t r=(first+end)>>1;
            size_t n=Tree.new_node();
            Tree[n].set(arr[r].m_key,Build(arr,first,r-1),Build(arr,r+1,end),end-first+1,end-first+1);
            return n;
        }
        void rebuild(size_t r)
        {
            //std::array<Node,Tree[r].m_rw> arr;
            size_t n=Tree[r].m_rw;
            Node arr[n*2];
            IOT(r,arr,1);
            Build(arr,1,n);
        }
        size_t check(size_t r,T K)
        {
            if(r==0)return 0;
            if((Tree[Tree[r].m_ls].m_w>Tree[r].m_w*alpha)||
            (Tree[Tree[r].m_rs].m_w>Tree[r].m_w*alpha)||
            (Tree[r].m_rw<Tree[r].m_w*alpha))
            {
                rebuild(r);
                return r;
            }
            else if(K==Tree[r].m_key)return r;
            else if(K<Tree[r].m_key)return check(Tree[r].m_ls,K);
            else return check(Tree[r].m_rs,K);
        }
        size_t f_insert(size_t r,T K,size_t &f)
        {
            if(r==0)
            {
                r=Tree.new_node();
                Tree[r].set(K);
                if(root==0)root=r;
                f=r;
                return r;
            }
            ++Tree[r].m_w,++Tree[r].m_rw;
            if(K<Tree[r].m_key)return f_insert(Tree[r].m_ls,K,Tree[r].m_ls);
            else if(K==Tree[r].m_key)
            {
                if(Tree[r].del==1)Tree[r].del=0,Tree[r].mol=1;
                else ++Tree[r].mol;
                return r;
            }else return f_insert(Tree[r].m_rs,K,Tree[r].m_rs);
        }
        size_t f_delete(size_t r,T K)
        {
            if(r==0)return 0;
            //--Tree[r].m_rw;
            if(K==Tree[r].m_key)
            {
                //std::cout<<"del,r="<<r<<" k="<<Tree[r].m_key<<'\n';
                if(Tree[r].mol>1)--Tree[r].mol;
                else Tree[r].del=1;
                --Tree[r].m_rw;
                return r;
            }
            size_t tmp=0;
            if(K<Tree[r].m_key)
            {
                (tmp=f_delete(Tree[r].m_ls,K))?(--Tree[r].m_rw):0;
                return tmp;
            }
            (tmp=f_delete(Tree[r].m_rs,K))?(--Tree[r].m_rw):0;
            return tmp;
        }
        size_t f_rank(size_t r,size_t rk)
        {
            /*if(r==0)return 0;
            if(Tree[r].m_rw<rk)return 0;
            if(rk==1)return r,std::cout<<'p',r;
            if(rk==0)return 0;
            size_t tmp=0;
            if(tmp=f_rank(Tree[r].m_ls,rk))return tmp;
            if(tmp=f_rank(Tree[r].m_rs,rk-Tree[Tree[r].m_ls].m_rw-1))return tmp;
            return r;*/
            if(r==0)return 0;
            if((rk==Tree[Tree[r].m_ls].m_rw+1)&&(!Tree[r].del))return r;
            if(rk<=Tree[Tree[r].m_ls].m_rw)return f_rank(Tree[r].m_ls,rk);
            return f_rank(Tree[r].m_rs,rk-Tree[Tree[r].m_ls].m_rw-(!Tree[r].del)*Tree[r].mol);
        }
        size_t f_findrk(size_t r,T K,size_t rk)
        {
            if(r==0)return 0;
            if(K==Tree[r].m_key)
            {
                if(Tree[r].del)return 0;
                else return rk+Tree[Tree[r].m_ls].m_rw+1;
            }
            if(K<Tree[r].m_key)return f_findrk(Tree[r].m_ls,K,rk);
            return f_findrk(Tree[r].m_rs,K,rk+Tree[Tree[r].m_ls].m_rw+(!Tree[r].del)*Tree[r].mol);
            /*if(r==0)return 0;
            size_t tmp=0;
            if(K==Tree[r].m_key)
            {
                if(Tree[r].del)tmp= 0;
                else tmp= rk+Tree[Tree[r].m_ls].m_rw+1;
            }
            else if(K<Tree[r].m_key)tmp= f_findrk(Tree[r].m_ls,K,rk);
            else tmp= f_findrk(Tree[r].m_rs,K,rk+Tree[Tree[r].m_ls].m_rw+(!Tree[r].del));
            if(tmp==0)return r;
            else return tmp;*/
        }
        size_t f_pre(size_t r,T K)
        {
            //std::cout<<"r="<<r<<'\n';
            if(r==0)return 0;
            size_t tmp;
            if(K>Tree[r].m_key)
            {
                tmp=f_pre(Tree[r].m_rs,K);
                return (tmp!=0)?tmp:r;
               //return 1;
            }
            else return f_pre(Tree[r].m_ls,K);
        }
        size_t f_lat(size_t r,T K)
        {
            //std::cout<<"r="<<r<<'\n';
            if(r==0)return 0;
            size_t tmp;
            if(K<Tree[r].m_key)
            {
                tmp=f_lat(Tree[r].m_ls,K);
                return (tmp!=0)?tmp:r;
               //return 1;
            }
            else return f_lat(Tree[r].m_rs,K);
        }
    public:
        SBTree()
        {
            alpha=(double)AL/100.00;
            root=0;
        }
        size_t insert(T K)
        {
            size_t tmp1,tmp2;
            tmp1=f_insert(root,K,tmp2);
            check(root,K);
            return tmp1;
        }
        size_t _delete(T K)
        {
            size_t tmp=f_delete(root,K);
            check(root,K);
            return tmp;
        }
        T rank(size_t rk)
        {
            if(rk>Tree.top+Tree.m_rec.size())return Tree[0].m_key;
            //std::cout<<'d';
            //Tree[f_rank(root,rk)].m_key
            int tmp=f_rank(root,rk);
            //std::cout<<'q'<<tmp<<'\n';
            return Tree[tmp].m_key;
        }
        size_t findrk(T K)
        {
            //return f_findrk(root,K,0);
            size_t tmp=f_findrk(root,K,0);
            if(!tmp)
            {
                f_insert(root,K,tmp);
                tmp=f_findrk(root,K,0);
                _delete(K);
            }
            return tmp;
        }
        T q5(T K)
        {
            return Tree[f_pre(root,K)].m_key;
        }
        T q6(T K)
        {
            return Tree[f_lat(root,K)].m_key;
        }
    };
}
using namespace std;
int main()
{
    SBTree::SBTree<int,800000> Tree;
    int n,opt,x;
    cin>>n;
    Tree.insert(-10000055);
    Tree.insert(10000088);
    while(n--)
    {
        cin>>opt>>x;
        //cout<<n<<endl;
        switch (opt)
        {
        case 1:
            Tree.insert(x);
            break;
        case 2:
            Tree._delete(x);
            break;
        case 3:
            cout<<Tree.findrk(x)-1<<endl;
            break;
        case 4:
            cout<<Tree.rank(x+1)<<endl;
            break;
        case 5:
            cout<<Tree.q5(x)<<endl;
            break;
        case 6:
            cout<<Tree.q6(x)<<endl;
            break;
        default:
            break;
        }
    }
    return 0;
}

测试结果

2024/7/8 15:43
加载中...