SPOJ–GSS系列的某一道题。。不懂。。就是一个区间翻转,最大连续子段和而已,强上treapAC。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<iostream>
using namespace std;
#define LL long long
const int N=201000;
int n,m,l,r;
char cmd[10];
inline void read(int &res){
static char ch;int flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
namespace TREAP{
struct Treap{
int rd,size,key;
LL lmax,rmax,ret,sum;
bool rev;
Treap *ch[2];
inline void setting(int v){
key=sum=v;
if(v<0)v=0;
lmax=rmax=ret=v;
}
inline void update(){
rev^=1;
swap(lmax,rmax);
}
inline void pushdown(){
if(rev){
swap(ch[0], ch[1]);
ch[0]->update();
ch[1]->update();
rev=0;
}
}
inline void pushup(){
size=ch[0]->size+ch[1]->size+1;
lmax=max(ch[0]->lmax,ch[0]->sum+key+ch[1]->lmax);
rmax=max(ch[1]->rmax,ch[1]->sum+key+ch[0]->rmax);
sum=ch[0]->sum+key+ch[1]->sum;
ret=max(ch[0]->ret,ch[1]->ret);
ret=max(ret,ch[0]->rmax+key+ch[1]->lmax);
}
Treap();
}tail,tree[N];
Treap *nul=&tail;
Treap *root=nul;
Treap::Treap(){
rd=rand();
ch[0]=ch[1]=nul;
if(this==nul)size=0;
else size=1;
}
Treap *merge(Treap *l,Treap *r){
if(l==nul)return r;
if(r==nul)return l;
if(l->rd>r->rd){
l->pushdown();
l->ch[1]=merge(l->ch[1],r);
l->pushup();
return l;
}else{
r->pushdown();
r->ch[0]=merge(l,r->ch[0]);
r->pushup();
return r;
}
}
inline void split(Treap *rt,int rank,Treap* &l,Treap* &r) {
rt->pushdown();
if(!rank){
l=nul;
r=rt;
return;
}
Treap *L,*R;
if(rt->ch[0]->size>=rank){
split(rt->ch[0],rank,L,R);
rt->ch[0]=R;l=L;r=rt;
}else{
split(rt->ch[1],rank-1-rt->ch[0]->size,L,R);
rt->ch[1]=L;l=rt;r=R;
}
rt->pushup();
}
inline void reverse(int l,int r){
Treap *L,*mid,*R;
split(root,l-1,L,mid);
split(mid,r-l+1,mid,R);
mid->update();
mid=merge(L,mid);
root=merge(mid,R);
}
inline void modify(int id,int v){
Treap *L,*mid,*R;
split(root,id-1,L,mid);
split(mid,1,mid,R);
mid->setting(v);
mid=merge(L,mid);
root=merge(mid,R);
}
inline void init(){
for(register int tmp,i=1;i<=n;i++){
read(tmp),tree[i].setting(tmp);
root=merge(root,&tree[i]);
}
}
inline LL query(int l,int r){
Treap *L,*mid,*R;
split(root,l-1,L,mid);
split(mid,r-l+1,mid,R);
LL ans=mid->ret;
mid=merge(L,mid);
root=merge(mid,R);
return ans;
}
}
using namespace TREAP;
int main(){
srand((unsigned)time(NULL));
read(n),read(m);
init();
while(m--){
scanf("%s",cmd),read(l),read(r);
if(cmd[0]=='Q')cout<<query(l,r)<<endl;
else if(cmd[0]=='R')reverse(l,r);
else modify(l, r);
}
return 0;
}