SPLAY 模板题
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define splay_pool NIL
using namespace std;
const int max_size=500010;
const int INF=(1ll<<31)-2;
struct Node {
int val,size;
Node *lch,*rch,*fa;
long long lsum,rsum,sum,msum;
bool flag,rev;
int setv;
Node(){
val=sum=flag=rev=size=0;
msum=lsum=rsum=-INF>>5;
}
Node(int _val,Node *_lch,Node *_rch,Node *_fa)
:val(_val),lch(_lch),rch(_rch),fa(_fa){
size=1;
lsum=rsum=sum=msum=_val;
flag=rev=0;
}
}splay_pool[max_size],*sp;
Node *pool[max_size];
struct splay_tree{
int tot;
Node *root,*head,*tail;
splay_tree(){}
void init(){
tot=0;
for(int i=1;i<max_size;i++)pool[tot++]=splay_pool+i;
new(NIL)Node;
sp=NIL;
NIL->lch=NIL->rch=NIL->fa=NIL;
head=new(pool[--tot])Node(-INF>>5,NIL,NIL,NIL);
tail=new(pool[--tot])Node(-INF>>5,NIL,NIL,NIL);
head->rch=tail;
tail->fa=head;
root=head;
update(root);
}
void rever(Node *t){
if(t==NIL)return;
t->rev=!t->rev;
swap(t->lch,t->rch);
swap(t->lsum,t->rsum);
}
void set(Node *t,int val){
if(t==NIL)return;
t->flag=true;
t->setv=val;
t->val=val;
t->sum=(long long)val*t->size;
t->rsum=t->lsum=t->msum=max((long long)val,t->sum);
}
void update(Node *t){
if(t==NIL)return;
t->size=t->lch->size+t->rch->size+1;
t->sum=t->val+t->rch->sum+t->lch->sum;
t->msum=max(max(t->lch->msum,t->rch->msum),max(max(t->lch->rsum+t->val,t->rch->lsum+t->val),max((long long)t->val,t->rch->lsum+t->val+t->lch->rsum)));
t->lsum=max(max(t->lch->lsum,t->lch->sum+t->val),t->lch->sum+t->val+t->rch->lsum);
t->rsum=max(max(t->rch->rsum,t->rch->sum+t->val),t->rch->sum+t->val+t->lch->rsum);
return ;
}
void pushdown(Node *t){
if(t==NIL)return ;
if(t->flag){
set(t->lch,t->setv);
set(t->rch,t->setv);
t->flag=false;
}
if(t->rev){
rever(t->lch);
rever(t->rch);
t->rev=false;
}
}
void zig(Node *t){
Node *f=t->fa,*c=t->rch;
if(t->fa==root)root=t;
else (f->fa->lch==f?f->fa->lch:f->fa->rch)=t;
t->fa=f->fa,t->rch=f,f->lch=c,f->fa=t,c->fa=f;
update(f),update(t);
}
void zag(Node *t){
Node *f=t->fa,*c=t->lch;
if(t->fa==root)root=t;
else (f->fa->lch==f?f->fa->lch:f->fa->rch)=t;
t->fa=f->fa,t->lch=f,f->rch=c,f->fa=t,c->fa=f;
update(f),update(t);
}
void splay(Node *&root,Node *t){
pushdown(t);
while(t!=root){
if(t->fa==root){
if(t->fa->lch==t)zig(t);
else zag(t);
}
else {
if(t->fa->fa->lch==t->fa){
if(t->fa->lch==t)zig(t->fa),zig(t);
else zag(t),zig(t);
}
else {
if(t->fa->lch==t)zig(t),zag(t);
else zag(t->fa),zag(t);
}
}
}
}
void select(Node *&root,int k){
Node *t=root;
while(true){
pushdown(t);
if(t->lch->size+1==k){
splay(root,t);
return;
}
if(t->lch->size>=k){
t=t->lch;
}
else {
k-=t->lch->size+1;
t=t->rch;
}
}
}
void build(int l,int r,int a[],Node *&t,Node *fa){
if(l>r)return;
int mid=(l+r)>>1;
t=new(pool[--tot])Node(a[mid],NIL,NIL,fa);
build(l,mid-1,a,t->lch,t);
build(mid+1,r,a,t->rch,t);
update(t);
}
void insert(int pos,int a[],int len){
select(root,pos+1);
select(root->rch,1);
build(1,len,a,root->rch->lch,root->rch);
update(root->rch);
update(root);
}
void dele(int pos,int tot){
select(root,pos);
select(root->rch,tot+1);
erase(root->rch->lch);
root->rch->lch=NIL;
update(root->rch);
update(root);
}
void modify(int pos,int tot,int val){
select(root,pos);
select(root->rch,tot+1);
set(root->rch->lch,val);
update(root->rch);
update(root);
}
void reverse(int pos,int tot){
select(root,pos);
select(root->rch,tot+1);
rever(root->rch->lch);
update(root->rch);
update(root);
}
int quarry(int pos,int tot){
select(root,pos);
select(root->rch,tot+1);
return root->rch->lch->sum;
}
int max_sum(){
return root->msum;
}
void erase(Node *t){
if(t==NIL)return;
erase(t->lch);
erase(t->rch);
pool[tot++]=t;
}
void dfs(Node *t){
if(t==NIL)return;
pushdown(t);
dfs(t->lch);
printf("%d\t",t->val);
dfs(t->rch);
}
int size(){
return root->size-2;
}
}T;
const int maxn=500010;
int data[maxn];
int main(){
int n,m;
// freopen("sequence10.in","r",stdin);
// freopen("sequence10.out","w",stdout);
while(~scanf("%d%d",&n,&m)){
T.init();
for(int i=1;i<=n;i++){
scanf("%d",&data[i]);
}
T.insert(0,data,n);
char flag[100];
int pos,len;
int l,r;
for(int i=0;i<m;i++){
scanf("%s",flag);
if(flag[0]=='G'){
scanf("%d%d",&pos,&len);
printf("%d\n",T.quarry(pos,len));
}
else if(flag[0]=='M'&&flag[3]=='-'){
printf("%d\n",T.max_sum());
}
else if(flag[0]=='I'){
scanf("%d%d",&pos,&len);
for(int i=1;i<=len;i++){
scanf("%d",data+i);
}
T.insert(pos,data,len);
}
else if(flag[0]=='D'){
scanf("%d%d",&pos,&len);
T.dele(pos,len);
}
else if(flag[0]=='M'){
int val;
scanf("%d%d%d",&pos,&len,&val);
T.modify(pos,len,val);
}
else {
scanf("%d%d",&pos,&len);
if(pos+len-1>T.size())
len=T.size()+1-pos;
T.reverse(pos,len);
}
}
}
return 0;
}