求调
查看原帖
求调
437398
EastIsRed楼主2024/4/10 12:18

删去throw部分后仅有30分,其余WA或RE。

#include<cstdio>
#include<chrono>
#include<random>
#include<algorithm>
#include<tuple>
#include<utility>
#include<vector>
#include<stdexcept>
template<typename T>
class maximum_substr_sum_struct{
    private:
        T sum,sum_l,sum_r,sum_max,single_val;
    public:
        typedef T lzd_type;
    private:
        lzd_type lzd;
    public:
        maximum_substr_sum_struct(T _val):sum(_val),sum_l(_val),sum_r(_val),sum_max(_val),single_val(_val),lzd(0){}
        maximum_substr_sum_struct(T _sum,T _sum_l,T _sum_r,T _sum_max,T _single_val)
        :sum(_sum),sum_l(_sum_l),sum_r(_sum_r),sum_max(_sum_max),single_val(_single_val),lzd(0){}
        bool lzd_exist()
        {
            return (bool)lzd;
        }
        void lzd_reset()
        {
            lzd=0;
        }
        const T get_lzd()
        {
            return lzd;
        }
        void load_self()
        {
            sum=sum_l=sum_r=sum_max=single_val;
        }
        void pre_merge(const maximum_substr_sum_struct& lhs)
        {
            sum_max=std::max({sum_max,lhs.sum_max,lhs.sum_r+sum_l});
            sum_l=std::max(lhs.sum_l,lhs.sum+sum_l);
            sum_r=std::max(sum_r,lhs.sum_r+sum);
            sum+=lhs.sum;
        }
        void modify(T _lzd,size_t len)
        {
            single_val=lzd=_lzd;
            sum=_lzd*len;
            if(_lzd>=0)
                sum_max=sum_l=sum_r=_lzd*len;
            else sum_max=sum_l=sum_r=_lzd;
        }
        void nxt_merge(const maximum_substr_sum_struct& rhs)
        {
            sum_max=std::max({sum_max,rhs.sum_max,rhs.sum_l+sum_r});
            sum_l=std::max(sum_l,sum+rhs.sum_l);
            sum_r=std::max(rhs.sum_r,sum_r+rhs.sum);
            sum+=rhs.sum;
        }
        void reverse()
        {
            std::swap(sum_l,sum_r);
        }
        const T get_sum()const
        {
            return sum;
        }
        const T get_sum_max()const
        {
            return sum_max;
        }
};
template<typename T,typename outer_covering_struct>
class rope_based_on_treap{
    private:
        static std::mt19937_64 rnd;
        struct node{
            outer_covering_struct val;
            node *ls,*rs;
            unsigned long long priority;
            bool reverse_tag;
            size_t cnt,size;
            node(const T& _val):val(_val),ls(nullptr),rs(nullptr),priority(rnd()),reverse_tag(false),cnt(1ULL),size(1ULL){}
            void recalc_size()
            {
                size=(ls==nullptr?0:ls->size)+cnt+(rs==nullptr?0:rs->size);
            }
            void push_up()
            {
                val.load_self();
                if(ls!=nullptr)
                    val.pre_merge(ls->val);
                if(rs!=nullptr)
                    val.nxt_merge(rs->val);
            }
            void reverse()
            {
                std::swap(ls,rs);
                val.reverse();
                reverse_tag=!reverse_tag;
            }
            void lzd_down()
            {
                if(reverse_tag)
                {
                    if(ls!=nullptr)
                        ls->reverse();
                    if(rs!=nullptr)
                        rs->reverse();
                    reverse_tag=false;
                }
                if(val.lzd_exist())
                {
                    if(ls!=nullptr)
                        ls->val.modify(val.get_lzd(),ls->size);
                    if(rs!=nullptr)
                        rs->val.modify(val.get_lzd(),rs->size);
                    val.lzd_reset();
                }
            }
        }*root;
        typedef std::tuple<node*,node*,node*> tuple_ppp;
        tuple_ppp split_by_rank(node* now,size_t rk)
        {
            if(now==nullptr)
                return {nullptr,nullptr,nullptr};
            now->lzd_down();
            size_t l_siz=(now->ls==nullptr?0ULL:now->ls->size);
            if(rk<l_siz)
            {
                tuple_ppp temp(split_by_rank(now->ls,rk));
                now->ls=std::get<2>(temp);
                now->recalc_size();
                now->push_up();
                std::get<2>(temp)=now;
                return temp;
            }
            else if(rk<l_siz+now->cnt)
            {
                tuple_ppp temp{now->ls,now,now->rs};
                now->ls=now->rs=nullptr;
                now->recalc_size();
                now->push_up();
                return temp;
            }
            else
            {
                tuple_ppp temp(split_by_rank(now->rs,rk-l_siz-now->cnt));
                now->rs=std::get<0>(temp);
                now->recalc_size();
                now->push_up();
                std::get<0>(temp)=now;
                return temp;
            }
        }
        node* merge(node* l,node* r)
        {
            if(l==nullptr)
                return r;
            if(r==nullptr)
                return l;
            l->lzd_down();
            r->lzd_down();
            if(l->priority>r->priority)
            {
                l->rs=merge(l->rs,r);
                l->recalc_size();
                l->push_up();
                return l;
            }
            else
            {
                r->ls=merge(l,r->ls);
                r->recalc_size();
                r->push_up();
                return r;
            }
        }
        tuple_ppp get_range(size_t l,size_t r)
        {
            tuple_ppp temp2(split_by_rank(root,r)),
                      temp1(split_by_rank(std::get<0>(temp2),l));
            if(std::get<1>(temp1)==nullptr||std::get<1>(temp1)->size<r-l)
            {
                fprintf(stderr,"ERROR: No Enough items\n");
                throw std::out_of_range("ERROR: No Enough items\n");
            }
            return {std::get<0>(temp1),merge(std::get<1>(temp1),std::get<2>(temp1)),merge(std::get<1>(temp2),std::get<2>(temp2))};
        }
        void destroy(node* now)
        {
            if(now==nullptr)
                return;
            destroy(now->ls);
            destroy(now->rs);
            delete now;
        }
    public:
        rope_based_on_treap():root(nullptr){}
        ~rope_based_on_treap()
        {
            destroy(root);
        }
        void clear()
        {
            destroy(root);
            root=nullptr;
        }
        size_t size()
        {
            return root==nullptr?0ULL:root->size;
        }
        bool empty()
        {
            return root==nullptr;
        }
        void insert(size_t pos,const std::vector<T>& arr)
        {
            tuple_ppp temp(split_by_rank(root,pos));
            node* new_part=nullptr;
            for(const T& item:arr)
                new_part=merge(new_part,new node(item));
            root=merge(merge(std::get<0>(temp),new_part),merge(std::get<1>(temp),std::get<2>(temp)));
        }
        void erase(size_t pos,size_t len)
        {
            tuple_ppp temp(get_range(pos,pos+len));
            destroy(std::get<1>(temp));
            root=merge(std::get<0>(temp),std::get<2>(temp));
        }
        void reverse(size_t pos,size_t len)
        {
            tuple_ppp temp(get_range(pos,pos+len));
            std::get<1>(temp)->reverse();
            root=merge(std::get<0>(temp),merge(std::get<1>(temp),std::get<2>(temp)));
        }
        const outer_covering_struct query(size_t pos,size_t len)
        {
            tuple_ppp temp(get_range(pos,pos+len));
            outer_covering_struct rev=std::get<1>(temp)->val;
            root=merge(std::get<0>(temp),merge(std::get<1>(temp),std::get<2>(temp)));
            return rev;
        }
        void modify(size_t pos,size_t len,typename outer_covering_struct::lzd_type val)
        {
            tuple_ppp temp(get_range(pos,pos+len));
            std::get<1>(temp)->val.modify(val,std::get<1>(temp)->size);
            root=merge(std::get<0>(temp),merge(std::get<1>(temp),std::get<2>(temp)));
        }
};
template<typename T,typename outer_covering_struct>
std::mt19937_64 rope_based_on_treap<T,outer_covering_struct>::rnd(std::chrono::high_resolution_clock::to_time_t(std::chrono::high_resolution_clock::now()));
inline long long read()
{
    long long m=0,n=1;
    char ch=getchar();
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            n=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        m=(m<<3)+(m<<1)+ch-'0';
        ch=getchar();
    }
    return m*n;
}
int n,m;
rope_based_on_treap<long long,maximum_substr_sum_struct<long long> >bst;
int main()
{
    n=read(),m=read();
    {
        std::vector<long long>arr(n);
        for(int i=0;i<n;i++)
            arr[i]=read();
        bst.insert(0,arr);
    }
    while(m--)
    {
        char op[20];
        int pos,tot;
        scanf("%s",op);
        if(!(op[0]=='M'&&op[3]=='-'))
            scanf("%d%d",&pos,&tot);
        if(op[0]=='I')
        {
            std::vector<long long>arr(tot);
            for(int i=0;i<tot;i++)
                arr[i]=read();
            bst.insert(pos,arr);
        }
        else if(op[0]=='D')
            bst.erase(pos-1,tot);
        else if(op[0]=='M'&&op[4]=='-')
        {
            int c;
            scanf("%d",&c);
            bst.modify(pos-1,tot,c);
        }
        else if(op[0]=='R')
            bst.reverse(pos-1,tot);
        else if(op[0]=='G')
            printf("%lld\n",bst.query(pos-1,tot).get_sum());
        else printf("%lld\n",bst.query(0,bst.size()).get_sum_max());
    }
    return 0;
}
2024/4/10 12:18
加载中...