传送门
题意:
平衡树的一系列操作。
题解:
Splay/无旋Treap
Splay:
#include<bits/stdc++.h>
using namespace std;
struct IO{
streambuf *ib,*ob;
inline void init(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
ib=cin.rdbuf();ob=cout.rdbuf();
}
inline int read(){
char ch=ib->sbumpc();int i=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();}
while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();}
return i*f;
}
inline void W(long long x){
static int buf[50];
if(!x){ob->sputc('0');ob->sputc('\n');return;}
if(x<0){ob->sputc('-');x=-x;}
while(x)buf[++buf[0]]=x%10,x/=10;
while(buf[0])ob->sputc(buf[buf[0]--]+'0');
ob->sputc('\n');
}
}io;
const int Maxn=5e5+50,INF=0x3f3f3f3f;
int n,m,nowtot;
struct node{
node *lc,*rc,*fa;
int val,sum,revtag,addtag,maxx,lmax,rmax,sze,isadd;
node();
inline void upt();
inline void add(int v){
val=v;sum=v*sze;
int t=(v>0)?sze:1;
maxx=lmax=rmax=t*v;
addtag=v;isadd=1;
}
inline void rev(){
swap(lc,rc);revtag^=1;
swap(lmax,rmax);
}
inline void pushdown();
}Pool[Maxn],*pool=Pool,*null=Pool;
node::node():lc(null),rc(null),val(-INF),maxx(-INF),lmax(-INF),rmax(-INF),isadd(0){}
void node::upt() {
sum=lc->sum+rc->sum+val;
lmax=max(lc->lmax,max(lc->sum+val,lc->sum+val+rc->lmax));
rmax=max(rc->rmax,max(rc->sum+val,rc->sum+val+lc->rmax));
sze=lc->sze+rc->sze+1;
maxx=max(val+max(lc->rmax,0)+max(rc->lmax,0),max(lc->maxx,rc->maxx));
}
void node::pushdown(){
if(revtag){
revtag=0;
if(lc!=null)lc->rev();
if(rc!=null)rc->rev();
}
if(isadd){
if(lc!=null)lc->add(addtag);
if(rc!=null)rc->add(addtag);
isadd=0;
}
}
struct RecyclePool{
node *que[Maxn];
int tail;
inline node* newnode(int val){
static node* tmp;
tmp=(tail?que[tail--]:++pool);
tmp->lc=tmp->rc=tmp->fa=null;tmp->isadd=0;
tmp->revtag=tmp->addtag=0;tmp->sze=1;
tmp->val=tmp->sum=tmp->maxx=tmp->lmax=tmp->rmax=val;
return tmp;
}
inline void recycle(node *u){
if(u==null)return;
que[++tail]=u;
recycle(u->lc);recycle(u->rc);
}
}recyclepool;
struct Splay{
node *rt;
inline bool which(node *x){return x->fa->lc==x;}
inline void rotate(node *x){
node *y=x->fa,*z=y->fa;
if(z!=null)(z->lc==y?z->lc:z->rc)=x;
x->fa=z;y->fa=x;node *b;
if(y->lc==x){b=x->rc;x->rc=y;y->lc=b;}
else{b=x->lc;x->lc=y;y->rc=b;}
if(b)b->fa=y;
y->upt();x->upt();
}
inline void splay(node *x,node *tar){
static node* que[Maxn];static int tail;
que[tail=1]=x;
for(node* y=x;y->fa!=null;y=y->fa)que[++tail]=y->fa;
for(int i=tail;i>=1;i--)que[i]->pushdown();
while(x->fa!=tar){
node *y=x->fa,*z=y->fa;
if(z!=tar)(which(x)^which(y))?(rotate(x)):(rotate(y));
rotate(x);
}
if(tar==null)rt=x;
}
inline void insert(node *&now,node *fa,int pos,int val){
now->pushdown();
if(now==null){
now=recyclepool.newnode(val);now->fa=fa;
splay(now,null);
return;
}
if(now->lc->sze+1>pos)insert(now->lc,now,pos,val);
else insert(now->rc,now,pos-now->lc->sze-1,val);
}
inline node* findpos(node *now,int pos){
now->pushdown();
if(now->lc->sze+1==pos)return now;
else if(now->lc->sze+1<pos)return findpos(now->rc,pos-now->lc->sze-1);
else return findpos(now->lc,pos);
}
inline int querysum(int l,int r){
splay(findpos(rt,l),null);splay(findpos(rt,r+2),rt);
return rt->rc->lc->sum;
}
inline void del(int l,int r){
splay(findpos(rt,l),null);splay(findpos(rt,r+2),rt);
recyclepool.recycle(rt->rc->lc);rt->rc->lc->fa=null;rt->rc->lc=null;
rt->rc->upt();rt->upt();
}
inline void rev(int l,int r){
splay(findpos(rt,l),null);splay(findpos(rt,r+2),rt);
rt->rc->lc->rev();rt->rc->upt();rt->upt();
}
inline void add(int l,int r,int v){
splay(findpos(rt,l),null);splay(findpos(rt,r+2),rt);
rt->rc->lc->add(v);rt->rc->upt();rt->upt();
}
inline node* build(node *fa,int *a,int l,int r){
int mid=(l+r)>>1;
node *tmp=recyclepool.newnode(a[mid]);tmp->fa=fa;
if(l==r)return tmp;
if(l<mid)tmp->lc=build(tmp,a,l,mid-1);
if(r>mid)tmp->rc=build(tmp,a,mid+1,r);
tmp->upt();
return tmp;
}
inline void insert(int pos,int *a,int tot){
node *tmp=build(null,a,1,tot);
splay(findpos(rt,pos+1),null);splay(findpos(rt,pos+2),rt);
tmp->fa=rt->rc;rt->rc->lc=tmp;rt->rc->upt();rt->upt();
}
}splay;
int a[Maxn];
inline void print(node *now){
if(now->lc!=null)print(now->lc);
cout<<now->val<<" ";
if(now->rc!=null)print(now->rc);
}
int main(){
io.init();n=io.read(),m=io.read();splay.rt=null;nowtot=n;
splay.insert(splay.rt,null,0,-INF);
splay.insert(splay.rt,null,1,-INF);
for(int i=1;i<=n;i++){splay.insert(splay.rt,null,i,io.read());}
for(int i=1;i<=m;i++){
static char ch[15];
cin>>(ch+1);
if(ch[1]=='G'){
int pos=io.read(),tot=io.read();
if(!tot){io.W(0);continue;}
io.W(splay.querysum(pos,pos+tot-1));
}
else if(ch[1]=='M'&&ch[3]=='X'){
if(!nowtot){io.W(0);continue;}
io.W(splay.rt->maxx);
}
else if(ch[1]=='I'){
int pos=io.read(),tot=io.read();nowtot+=tot;
for(int j=1;j<=tot;j++){
a[j]=io.read();
}
splay.insert(pos,a,tot);
}
else if(ch[1]=='D'){
int pos=io.read(),tot=io.read();nowtot-=tot;
splay.del(pos,pos+tot-1);
}
else if(ch[1]=='R'){
int pos=io.read(),tot=io.read();
splay.rev(pos,pos+tot-1);
}
else{
int pos=io.read(),tot=io.read(),c=io.read();
if(!tot)continue;
splay.add(pos,pos+tot-1,c);
}
}
}
无旋Treap:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned int uint;
struct IO{
streambuf *ib,*ob;
inline void init(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
ib=cin.rdbuf();ob=cout.rdbuf();
}
inline int read(){
char ch=ib->sbumpc();int i=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();}
while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();}
return i*f;
}
inline void W(long long x){
static int buf[50];
if(!x){ob->sputc('0');ob->sputc('\n');return;}
if(x<0){ob->sputc('-');x=-x;}
while(x)buf[++buf[0]]=x%10,x/=10;
while(buf[0])ob->sputc(buf[buf[0]--]+'0');
ob->sputc('\n');
}
inline uint unit(){
static uint status0=23333;
status0^=status0<<13;
status0^=status0>>17;
status0^=status0<<5;
return status0;
}
}io;
const int Maxn=5e5+50,INF=0x3f3f3f3f;
int n,m,nowtot;
struct node{
node *lc,*rc;
int val,sum,revtag,addtag,maxx,lmax,rmax,sze,isadd;
uint pri;
node();
inline void upt();
inline void add(int v){
val=v;sum=v*sze;
int t=(v>0)?sze:1;
maxx=lmax=rmax=t*v;
addtag=v;isadd=1;
}
inline void rev(){
swap(lc,rc);revtag^=1;
swap(lmax,rmax);
}
inline void pushdown();
}Pool[Maxn],*pool=Pool,*null=Pool;
typedef pair<node*,node*> pii;
node::node():lc(null),rc(null),val(-INF),maxx(-INF),lmax(-INF),rmax(-INF),isadd(0), revtag(0){}
void node::upt() {
sum=lc->sum+rc->sum+val;
lmax=max(lc->lmax,max(lc->sum+val,lc->sum+val+rc->lmax));
rmax=max(rc->rmax,max(rc->sum+val,rc->sum+val+lc->rmax));
sze=lc->sze+rc->sze+1;
maxx=max(val+max(lc->rmax,0)+max(rc->lmax,0),max(lc->maxx,rc->maxx));
}
void node::pushdown(){
if(revtag){
revtag=0;
if(lc!=null)lc->rev();
if(rc!=null)rc->rev();
}
if(isadd){
if(lc!=null)lc->add(addtag);
if(rc!=null)rc->add(addtag);
isadd=0;
}
}
struct RecyclePool{
node *que[Maxn];
int tail;
inline node* newnode(int val){
static node* tmp;
tmp=(tail?que[tail--]:++pool);
tmp->lc=tmp->rc=null;tmp->isadd=0;tmp->pri=io.unit();
tmp->revtag=tmp->addtag=0, tmp->sze=1;
tmp->val=tmp->maxx=tmp->lmax=tmp->rmax=val;
return tmp;
}
inline void recycle(node *u){
if(u==null)return;
que[++tail]=u;
recycle(u->lc);recycle(u->rc);
}
}recyclepool;
struct Treap{
node *rt;
inline node* merge(node *x,node *y){
if(x==null)return y;
if(y==null)return x;
x->pushdown(), y->pushdown();
if(x->pri < y->pri){
x->rc = merge(x->rc, y), x->upt();
return x;
}
else{
y->lc = merge(x, y->lc), y->upt();
return y;
}
}
inline pii split(node *u,int k){
if(u==null) return pii(null, null);
u->pushdown();
if (u->lc->sze + 1 <= k){
pii tr = split(u->rc, k - u->lc->sze - 1);
u->rc = tr.first, u->upt();
return pii(u,tr.second);
}
else {
pii tr = split(u->lc,k);
u->lc = tr.second;u->upt();
return pii(tr.first,u);
}
}
inline int querysum(int l,int tot){
pii tr=split(rt,l-1);pii tr2=split(tr.second,tot);
int ans = tr2.first->sum;
rt=merge(tr.first,merge(tr2.first,tr2.second));
return ans;
}
inline void del(int l,int tot){
pii tr=split(rt,l-1);pii tr2=split(tr.second,tot);
recyclepool.recycle(tr2.first);
rt=merge(tr.first,tr2.second);
}
inline void rev(int l,int tot){
pii tr=split(rt,l-1);pii tr2=split(tr.second,tot);
tr2.first->rev();
rt=merge(tr.first,merge(tr2.first,tr2.second));
}
inline void add(int l,int tot,int val){
pii tr=split(rt,l-1);pii tr2=split(tr.second,tot);
tr2.first->add(val);
rt=merge(tr.first,merge(tr2.first,tr2.second));
}
inline node* build(int *a,int n){
static node* st[Maxn],*pre;static int tail;
tail=0;
for(int i=0;i<n;i++){
node *u=recyclepool.newnode(a[i]);pre=null;
while(tail&&st[tail]->pri>u->pri)
st[tail]->upt(),pre=st[tail--];
if(tail)st[tail]->rc=u;
u->lc=pre;st[++tail]=u;
}
while(tail)st[tail--]->upt();
return st[1];
}
inline void insert(int *a, int n, int pos) {
node *u = build(a, n);
pii t = split(rt, pos);
rt = merge(merge(t.first, u), t.second);
}
}treap;
int a[Maxn];
int main(){
io.init();n=io.read(),m=io.read();treap.rt=null;nowtot=n;
for(int i=0;i<n;i++){a[i] = io.read();}
treap.rt=treap.build(a,n);
for(int i=1;i<=m;i++){
static char ch[15];
cin>>(ch+1);
if(ch[1]=='G'){
int pos=io.read(),tot=io.read();
if(!tot){io.W(0);continue;}
io.W(treap.querysum(pos,tot));
}
else if(ch[1]=='M'&&ch[3]=='X'){
if(!nowtot){io.W(0);continue;}
io.W(treap.rt->maxx);
}
else if(ch[1]=='I'){
int pos=io.read(),tot=io.read();nowtot+=tot;
for(int j=0;j<tot;j++){
a[j] = io.read();
}
treap.insert(a, tot, pos);
}
else if(ch[1]=='D'){
int pos=io.read(),tot=io.read();nowtot-=tot;
if(!tot)continue;
treap.del(pos,tot);
}
else if(ch[1]=='R'){
int pos=io.read(),tot=io.read();
if(!tot)continue;
treap.rev(pos,tot);
}
else{
int pos=io.read(),tot=io.read(),c=io.read();
if(!tot)continue;
treap.add(pos,tot,c);
}
}
}