【BZOJ1500】【Noi2005】维修数列
题意原题很清楚了。
解题思路:裸的平衡树操作,注意动态开点即可。
细节还是比较多的,具体参见代码吧。。。
#include <stdio.h> #include <algorithm> #define r register #define max(a,b) ((a)>(b)?(a):(b)) inline int in(){ r int x=0;r bool f=0;r char c; for (;(c=getchar())<'0'||c>'9';) f=c=='-'; for (x=c-'0';(c=getchar())>='0'&&c<='9';) x=(x<<3)+(x<<1)+c-'0'; return f?-x:x; } namespace Treap{ inline int Rand(){ static int x=23333; return x^=x<<13,x^=x>>17,x^=x<<5; } struct node{ node *ls,*rs; bool rev,sam; int val,sz,pri,sum,lx,rx,mx; node(int x):val(x),sz(1),pri(Rand()){sum=mx=lx=rx=val,rev=sam=0,ls=rs=NULL;} inline void reverse(){ std::swap(ls,rs); if(ls) ls->rev^=1,std::swap(ls->lx,ls->rx); if(rs) rs->rev^=1,std::swap(rs->lx,rs->rx); } inline void combine(){ sum=mx=lx=rx=val; sz=1; if(ls) sum+=ls->sum,sz+=ls->sz; if(rs) sum+=rs->sum,sz+=rs->sz; if(ls){ lx=ls->lx; lx=max(lx,ls->sum+val); if(rs) lx=max(lx,ls->sum+val+rs->lx); }else if(rs) lx=max(lx,val+rs->lx); if(rs){ rx=rs->rx; rx=max(rx,rs->sum+val); if(ls) rx=max(rx,rs->sum+val+ls->rx); }else if(ls) rx=max(rx,val+ls->rx); if(ls){ mx=max(mx,ls->mx); mx=max(mx,ls->rx+val); } if(rs){ mx=max(mx,rs->mx); mx=max(mx,rs->lx+val); } if(ls&&rs) mx=max(mx,ls->rx+val+rs->lx); } inline void pushdown(){ if (sam){ if (ls){ ls->val=val; ls->sum=ls->sz*val; ls->sam=1; if (val>0) ls->mx=ls->lx=ls->rx=ls->sum; else ls->mx=ls->lx=ls->rx=val; } if (rs){ rs->val=val; rs->sum=rs->sz*val; rs->sam=1; if (val>0) rs->mx=rs->lx=rs->rx=rs->sum; else rs->mx=rs->lx=rs->rx=val; }sam=0; } if (rev) reverse(),rev=0; } }*root; struct Droot{node *a,*b;}; inline int Size(node *x){return x?x->sz:0;} node *merge(node *a,node *b){ if (!a) return b; if (!b) return a; if (a->pri<b->pri){ a->pushdown(); a->rs=merge(a->rs,b); a->combine(); return a; }else{ b->pushdown(); b->ls=merge(a,b->ls); b->combine(); return b; } } Droot split(node *x,int k){ if (!x) return (Droot){NULL,NULL}; r Droot y; x->pushdown(); if (Size(x->ls)>=k){ y=split(x->ls,k); x->ls=y.b; x->combine(); y.b=x; }else{ y=split(x->rs,k-Size(x->ls)-1); x->rs=y.a;x->combine();y.a=x; }return y; } inline void trash(node *&x){ if (!x) return; trash(x->ls),trash(x->rs); delete x;x=NULL; } inline int Get_Sum(int s,int l){ if (l==0) return 0; r Droot x=split(root,s-1); r Droot y=split(x.b,l); r int ans=y.a->sum; root=merge(merge(x.a,y.a),y.b); return ans; } inline int Get_Max(){return root?root->mx:0;} inline void Delete(int s,int l){ r Droot x=split(root,s-1); r Droot y=split(x.b,l); root=merge(x.a,y.b);trash(y.a); } inline void Make_Same(int s,int l,int val){ r Droot x=split(root,s-1); r Droot y=split(x.b,l); y.a->val=val;y.a->sam=1;y.a->rev=0,y.a->sum=y.a->sz*val; if (val>0) y.a->mx=y.a->lx=y.a->rx=y.a->sum; else y.a->mx=y.a->lx=y.a->rx=val; root=merge(merge(x.a,y.a),y.b); } inline void Reverse(int s,int l){ r Droot x=split(root,s-1); r Droot y=split(x.b,l); y.a->rev=1; std::swap(y.a->lx,y.a->rx); root=merge(merge(x.a,y.a),y.b); } inline node *insert(int k){ if (!k) return NULL; if (k==1){ r node *ans=new node(in()); return ans; } r node *a,*b; a=insert(k>>1); b=insert(k-(k>>1)); return merge(a,b); } inline void Insert(){ r int pos=in(),n=in(); r node *ans=insert(n); r Droot x=split(root,pos); root=merge(merge(x.a,ans),x.b); } }using namespace Treap;int n,q; void init(){n=in(),q=in();root=insert(n);} void solve(){ while(q--){ r char op[20];scanf("%s",op); if (op[0]=='M'){ if (op[2]=='K'){ r int x=in(),n=in(); Make_Same(x,n,in()); }else printf("%d\n",Get_Max()); } else{ switch(op[0]){ case 'I':Insert();break; case 'D':{r int x=in();Delete(x,in());break;} case 'R':{r int x=in();Reverse(x,in());break;} case 'G':{r int x=in();printf("%d\n",Get_Sum(x,in()));break;} } } } } int main(){init(); solve(); return 0;}