传送门
解析:
Treap实现一下GSS3的操作就行了
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline int getint(){
re char c;
re bool f=0;
while(!isdigit(c=gc()))f^=c=='-';re int num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return f?-num:num;
}
inline char getalpha(){
re char c;
while(!isalpha(c=gc()));return c;
}
}
using namespace IO;
typedef std::pair<int,int> pii;
#define mp std::make_pair
inline unsigned int rnd(){
static int state=19491001;
state^=state<<17;
state^=state>>13;
state^=state<<3;
return state;
}
inline int max(int a,int b){return a<b?b:a;}
cs int N=2e5+5;
struct node{
int lmx,rmx,mx,sum;
node(){}
node(cs int &_val):lmx(_val),rmx(_val),mx(_val),sum(_val){}
node(cs int &_lmx,cs int &_rmx,cs int &_mx,cs int &_sum):lmx(_lmx),rmx(_rmx),mx(_mx),sum(_sum){}
friend node operator+(cs node &l,cs node &r){
node t;
t.sum=l.sum+r.sum;
t.lmx=max(l.lmx,l.sum+r.lmx);
t.rmx=max(r.rmx,r.sum+l.rmx);
t.mx=max(max(r.mx,l.mx),l.rmx+r.lmx);
return t;
}
}t[N],unit=node(-0x3f3f3f3f,-0x3f3f3f3f,-0x3f3f3f3f,0);
int son[N][2],val[N],siz[N];
int del[N>>1],top;
inline int newnode(cs int &_val){
static int tot=0;
int now=top?del[top--]:++tot;
son[now][0]=son[now][1]=0;
t[now]=node(val[now]=_val);
siz[now]=1;
return now;
}
inline void pushup(int u){
siz[u]=siz[son[u][0]]+siz[son[u][1]]+1;
t[u]=t[son[u][0]]+node(val[u])+t[son[u][1]];
}
inline pii split(int now,cs int &key){
if(!now)return mp(0,0);
pii res;
if(siz[son[now][0]]+1<=key){
res=split(son[now][1],key-siz[son[now][0]]-1);
son[now][1]=res.first;
res.first=now;
}
else {
res=split(son[now][0],key);
son[now][0]=res.second;
res.second=now;
}
pushup(now);
return res;
}
inline int merge(int a,int b){
if(!a||!b)return a|b;
if((ll)siz[a]*rnd()>(ll)siz[b]*rnd()){
son[a][1]=merge(son[a][1],b);
pushup(a);
return a;
}
else {
son[b][0]=merge(a,son[b][0]);
pushup(b);
return b;
}
}
inline int build(int l,int r){
if(l==r)return newnode(getint());
int mid=(l+r)>>1;
int lc=build(l,mid),rc=build(mid+1,r);
return merge(lc,rc);
}
int rt;
inline void Ins(int pos,int val){
pii res=split(rt,pos-1);
rt=merge(res.first,merge(newnode(val),res.second));
}
inline void Del(int pos){
pii res1=split(rt,pos-1);
pii res2=split(res1.second,1);
del[++top]=res2.first;
rt=merge(res1.first,res2.second);
}
inline void Change(int pos,int _val){
pii res1=split(rt,pos-1);
pii res2=split(res1.second,1);
val[res2.first]=_val;
t[res2.first]=node(_val);
rt=merge(res1.first,merge(res2.first,res2.second));
}
inline void inorder_dfs(int u){
if(!u)return ;
inorder_dfs(son[u][0]);
std::cerr<<val[u]<<" ";
inorder_dfs(son[u][1]);
}
inline int Query(int l,int r){
pii res1=split(rt,r);
pii res2=split(res1.first,l-1);
int ans=t[res2.second].mx;
rt=merge(merge(res2.first,res2.second),res1.second);
return ans;
}
int n,m;
signed main(){
t[0]=unit;
n=getint();
rt=build(1,n);
m=getint();
while(m--)switch(getalpha()){
case 'I':{
int pos=getint(),val=getint();
Ins(pos,val);
break;
}
case 'D':Del(getint());break;
case 'R':{
int pos=getint(),val=getint();
Change(pos,val);
break;
}
case 'Q':{
int l=getint(),r=getint();
std::cout<<Query(l,r)<<"\n";
break;
}
}
return 0;
}