1. 程式人生 > >P2042 [NOI2005]維護數列

P2042 [NOI2005]維護數列

mes clear ostream pac arr amp out min %s

P2042 [NOI2005]維護數列

splay

毒瘤模板splay

自行體會

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue> 
#define re register
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
template 
<typename T> inline T max(T &a,T &b) {return a>b ?a:b;} template <typename T> inline void read(T &x){ char c=getchar(); x=0; bool f=1; while(!isdigit(c)) f= !f||c==- ? 0:1,c=getchar(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar(); x
= f ? x:-x; } template <typename T> inline void output(T x){ if(!x) {putchar(48); return ;} if(x<0) putchar(-),x=-x; int wt[50],l=0; while(x) wt[++l]=x%10,x/=10; while(l) putchar(wt[l--]+48); } struct data{ int fa,ch[2],v,sz,sum,lx,rx,mx,tag,rev; void clear(){fa=ch[0
]=ch[1]=v=sz=sum=lx=rx=mx=tag=rev=0;} }a[500005]; int n,m,u,rt,val[500005]; queue <int> lit; inline void pdn(int o){ int lc=a[o].ch[0],rc=a[o].ch[1]; if(a[o].tag){ a[o].tag=a[o].rev=0; a[lc].tag=a[rc].tag=1; a[lc].v=a[rc].v=a[o].v; a[lc].sum=a[lc].sz*a[o].v; a[rc].sum=a[rc].sz*a[o].v; if(a[o].v>=0){ a[lc].lx=a[lc].rx=a[lc].mx=a[lc].sum; a[rc].lx=a[rc].rx=a[rc].mx=a[rc].sum; }else{ a[lc].lx=a[lc].rx=0; a[lc].mx=a[lc].v; a[rc].lx=a[rc].rx=0; a[rc].mx=a[rc].v; } /* a[lc].mx=max(a[o].v,a[lc].sum); a[rc].mx=max(a[o].v,a[rc].sum); a[lc].lx=a[lc].rx=max(0,a[lc].sum); a[rc].lx=a[rc].rx=max(0,a[rc].sum);*/ //註意不等價! }if(!a[o].rev) return; a[o].rev=0; a[lc].rev^=1; a[rc].rev^=1; swap(a[lc].ch[0],a[lc].ch[1]); swap(a[rc].ch[0],a[rc].ch[1]); swap(a[lc].lx,a[lc].rx); swap(a[rc].lx,a[rc].rx); } inline void mtn(int o){ if(!o) return; int lc=a[o].ch[0],rc=a[o].ch[1]; a[o].sz=a[lc].sz+a[rc].sz+1; a[o].sum=a[lc].sum+a[rc].sum+a[o].v; a[o].mx=max(a[lc].rx+a[o].v+a[rc].lx,max(a[lc].mx,a[rc].mx)); a[o].lx=max(a[lc].lx,a[lc].sum+a[o].v+a[rc].lx); a[o].rx=max(a[rc].rx,a[lc].rx+a[o].v+a[rc].sum); } inline void rte(int x,int &k){ int y=a[x].fa,z=a[y].fa; int l=(a[y].ch[1]==x),r=l^1; if(y==k) k=x; else a[z].ch[a[z].ch[1]==y]=x; a[a[x].ch[r]].fa=y,a[y].fa=x,a[x].fa=z; a[y].ch[l]=a[x].ch[r],a[x].ch[r]=y; mtn(y); mtn(x); } inline void splay(int x,int &k){ for(;x!=k;rte(x,k)){ int y=a[x].fa,z=a[y].fa; if(y!=k){ if((a[y].ch[0]==x)^(a[z].ch[0]==y)) rte(x,k); else rte(y,k); } } } inline int find(int x,int k){ pdn(x); int lc=a[x].ch[0],rc=a[x].ch[1]; if(a[lc].sz+1==k) return x; if(a[lc].sz>=k) return find(lc,k); else return find(rc,k-a[lc].sz-1); } inline int split(int x,int k){ int l=find(rt,x),r=find(rt,x+1+k); splay(l,rt); splay(r,a[l].ch[1]); return a[r].ch[0]; }
//-----↑splay核心↑------ inline
void build(int &o,int l,int r,int _fa){ //建樹 if(l>r) return; if(!o){ if(!lit.empty()) o=lit.front(),lit.pop(); else o=++u; }int mid=l+((r-l)>>1); a[o].sz=1; a[o].fa=_fa; a[o].tag=a[o].rev=0; a[o].sum=a[o].v=a[o].mx=val[mid]; a[o].lx=a[o].rx=max(0,a[o].v); build(a[o].ch[0],l,mid-1,o); build(a[o].ch[1],mid+1,r,o); mtn(o); } inline void ins(int x,int k){ //插入 for(re int i=1;i<=k;++i) read(val[i]); split(x+1,0); int _rt=0,y=a[rt].ch[1]; build(_rt,1,k,y); a[y].ch[0]=_rt; mtn(y); mtn(rt); } inline void reuse(int x){ if(!x) return; reuse(a[x].ch[0]); reuse(a[x].ch[1]); a[x].clear(); lit.push(x); } inline void remov(int x,int k){ //刪除 int _rt=split(x,k); int y=a[rt].ch[1]; reuse(_rt); a[y].ch[0]=0; mtn(y); mtn(rt); } inline void modify(int x,int k,int v){ //修改 int _rt=split(x,k); a[_rt].tag=1,a[_rt].v=v; a[_rt].sum=a[_rt].sz*v; a[_rt].lx=a[_rt].rx=max(0,a[_rt].sum); a[_rt].mx=max(v,a[_rt].sum); mtn(a[_rt].fa); mtn(rt); } inline void reverse(int x,int k){ //旋轉 int _rt=split(x,k); if(a[_rt].tag) return; a[_rt].rev^=1; swap(a[_rt].ch[0],a[_rt].ch[1]); swap(a[_rt].lx,a[_rt].rx); mtn(a[_rt].fa); mtn(rt); } inline int query(int x,int k){ int _rt=split(x,k); return a[_rt].sum; } int main(){ read(n); read(m); int q1,q2,q3; char opt[14]; val[1]=val[n+2]=-2e9; for(re int i=2;i<=n+1;++i) read(val[i]); build(rt,1,n+2,0); for(re int i=1;i<=m;++i){ scanf("%s",opt); if(opt[0]==G) read(q1),read(q2),output(query(q1,q2)),putchar(\n); else if(opt[0]==I) read(q1),read(q2),ins(q1,q2); else if(opt[0]==D) read(q1),read(q2),remov(q1,q2); else if(opt[0]==R) read(q1),read(q2),reverse(q1,q2); else{ if(opt[2]==X) output(a[rt].mx),putchar(\n); else read(q1),read(q2),read(q3),modify(q1,q2,q3); } }return 0; }

P2042 [NOI2005]維護數列