删去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;
}