[NOI2005]维护数列(区间splay)
作者:互联网
打这玩意儿真是要了我的老命
Description
请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格)
Code
#include <cstdio> #include <cstdlib> #include <algorithm> #define TAGNONE 10000001 using namespace std; const int N=1e6+10; struct node { int size,rev,ch[2],res,prer,prel,tag,fa,sum,val; void clear() { size=rev=ch[0]=ch[1]=res=prer=prel=fa=sum=val=0; tag=TAGNONE; } }f[N]; int x,id[N],tot,n,ru[N],rt,pos,len,d[N],m,cnt; char s[20]; int get() { if(tot==0) return ++cnt; int x=ru[tot--]; return x; } void c_val(int x,int y) { if(!x) return ; f[x].tag=f[x].val=y; f[x].sum=y*f[x].size; f[x].prel=f[x].prer=max(0,f[x].sum); f[x].res=max(y,f[x].sum); } void c_rev(int x) { swap(f[x].ch[0],f[x].ch[1]); swap(f[x].prer,f[x].prel); f[x].rev^=1; } void push_up(int x) { int lc=f[x].ch[0],rc=f[x].ch[1]; f[x].size=f[lc].size+f[rc].size+1; f[x].sum=f[lc].sum+f[rc].sum+f[x].val; f[x].res=max(max(f[lc].res,f[rc].res),f[lc].prer+f[rc].prel+f[x].val); f[x].prel=max(f[lc].prel,f[lc].sum+f[rc].prel+f[x].val); f[x].prer=max(f[rc].prer,f[rc].sum+f[lc].prer+f[x].val); } void push_down(int x) { int lc=f[x].ch[0],rc=f[x].ch[1]; if(f[x].tag!=TAGNONE) { c_val(lc,f[x].tag); c_val(rc,f[x].tag); f[x].tag=TAGNONE; } if(f[x].rev) { c_rev(lc),c_rev(rc); f[x].rev=0; } } int kth(int k) { int x=rt; while(1) { push_down(x); int lc=f[x].ch[0],rc=f[x].ch[1]; if(f[lc].size+1==k) return x; else if(f[lc].size>=k) x=lc; else k-=f[lc].size+1,x=rc; } } void rotate(int x) { int y=f[x].fa,z=f[y].fa; int wh=(x==f[y].ch[1]); f[f[x].ch[wh^1]].fa=y; f[y].ch[wh]=f[x].ch[wh^1]; f[x].ch[wh^1]=y; f[y].fa=x,f[x].fa=z; if(z) f[z].ch[y==f[z].ch[1]]=x; push_up(y),push_up(x); } void splay(int x,int y) { for(int fx=f[x].fa;fx=f[x].fa,fx!=y;rotate(x)) if(f[fx].fa!=y) rotate((fx==f[f[fx].fa].ch[1])^(x==f[fx].ch[1])?x:fx); if(!y) rt=x; } int split(int pos,int len) { int x=kth(pos),y=kth(pos+len+1); splay(x,0),splay(y,x); return f[y].ch[0]; } void creat(int x,int y) { f[x].val=f[x].sum=f[x].res=y; f[x].prel=f[x].prer=max(y,0); f[x].rev=0,f[x].tag=TAGNONE; f[x].size=1; } void build(int l,int r,int fa) { int mid=(l+r)>>1; int x=id[mid],fx=id[fa]; if(l==r) creat(x,d[mid]); if(l<mid) build(l,mid-1,mid); if(mid<r) build(mid+1,r,mid); f[x].tag=TAGNONE,f[x].val=d[mid],f[x].fa=fx; push_up(x); f[fx].ch[mid>=fa]=x; } void insert(int x,int len) { for(int i=1;i<=len;i++) scanf("%d",&d[i]),id[i]=get(); build(1,len,0); int a=kth(x+1),b=kth(x+2); splay(a,0),splay(b,a); int c=id[(1+len)>>1]; f[c].fa=b,f[b].ch[0]=c; push_up(b),push_up(a); } void remove(int x) { if(f[x].ch[0]) remove(f[x].ch[0]); if(f[x].ch[1]) remove(f[x].ch[1]); ru[++tot]=x,f[x].clear(); } void eraser(int k,int len) { int x=split(k,len),y=f[x].fa; remove(x); f[y].ch[0]=0; push_up(y),push_up(f[y].fa); } void update(int pos,int len,int k) { int x=split(pos,len); c_val(x,k); push_up(f[x].fa),push_up(rt); } void rever(int pos,int len) { int x=split(pos,len); if(f[x].tag!=TAGNONE) return; c_rev(x); push_up(f[x].fa),push_up(rt); } void query(int pos,int len) { int x=split(pos,len); printf("%d\n",f[x].sum); } int main() { scanf("%d%d",&n,&m); f[0].res=d[1]=d[n+2]=-1<<30; for(int i=1;i<=n;i++) scanf("%d",&d[i+1]); for(int i=1;i<=n+2;i++) id[i]=i; build(1,n+2,0); rt=(n+3)>>1,cnt=n+2; while(m--) { scanf("%s",s); if(s[0]=='M' && s[1]=='A' && s[2]=='X') printf("%d\n",f[rt].res); else scanf("%d%d",&pos,&len); if(s[0]=='I') insert(pos,len); if(s[0]=='D') eraser(pos,len); if(s[0]=='M' && s[1]=='A' && s[2]=='K') scanf("%d",&x),update(pos,len,x); if(s[0]=='R') rever(pos,len); if(s[0]=='G') query(pos,len); } return 0; }
标签:ch,数列,int,pos,len,splay,fa,NOI2005,lc 来源: https://www.cnblogs.com/hsez-cyx/p/12247579.html