bzoj1500: [NOI2005]维修数列
Posted invoid
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1500: [NOI2005]维修数列相关的知识,希望对你有一定的参考价值。
splay.
就是splay,没别的了。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 600000 + 10; const int inf = 0x3f3f3f3f; struct Splay { int v[maxn],s[maxn],sum[maxn]; int l[maxn],r[maxn],f[maxn]; int maxl[maxn],maxr[maxn],maxs[maxn]; int same[maxn],rev[maxn]; int q[maxn+1000],h,t; int root; int newnode() { int x=q[h++]; if(h==maxn) h=0; return x; } void recycle(int x) { if(x==0) return; recycle(l[x]); recycle(r[x]); q[t++]=x; if(t==maxn) t=0; } void reverse(int x) { swap(l[x],r[x]); swap(maxl[x],maxr[x]); rev[x]^=1; } void make_same(int x,int val) { same[x]=v[x]=val; sum[x]=s[x]*val; if(val>0) maxl[x]=maxr[x]=maxs[x]=sum[x]; else {maxl[x]=maxr[x]=0; maxs[x]=val;} } void push(int x) { if(same[x]!=inf) { make_same(l[x],same[x]); make_same(r[x],same[x]); same[x]=inf; if(rev[x]) rev[x]=0; } if(rev[x]) { reverse(l[x]); reverse(r[x]); rev[x]=0; } } void update(int x) { sum[x]=sum[l[x]]+sum[r[x]]+v[x]; maxl[x]=max(maxl[l[x]],sum[l[x]]+v[x]+maxl[r[x]]); maxr[x]=max(maxr[r[x]],sum[r[x]]+v[x]+maxr[l[x]]); maxs[x]=max(max(maxs[l[x]],maxs[r[x]]),maxr[l[x]]+v[x]+maxl[r[x]]); s[x]=s[l[x]]+s[r[x]]+1; } void lr(int x) { int y=f[x]; r[y]=l[x]; if(l[x]) f[l[x]]=y; f[x]=f[y]; if(root==y) root=x; else if(l[f[y]]==y) l[f[y]]=x; else r[f[y]]=x; f[y]=x; l[x]=y; update(y); update(x); } void rr(int x) { int y=f[x]; l[y]=r[x]; if(r[x]) f[r[x]]=y; f[x]=f[y]; if(root==y) root=x; else if(l[f[y]]==y) l[f[y]]=x; else r[f[y]]=x; f[y]=x; r[x]=y; update(y); update(x); } void rotate(int x) { if(l[f[x]]==x) rr(x); else lr(x); } void splay(int x,int target=0) { while(f[x]!=target) { if(f[f[x]]==target) rotate(x); else if((l[f[x]]==x)==(l[f[f[x]]]==f[x])) {rotate(f[x]); rotate(x);} else {rotate(x); rotate(x);} } } int find(int k) { int x=root; push(x); while(k!=s[l[x]]+1) { if(k>s[l[x]]+1) {k-=s[l[x]]+1; x=r[x];} else x=l[x]; push(x); } return x; } void Insert(int pos,int tot) { splay(find(pos+1),0); splay(find(pos+2),root); build(l[r[root]],r[root],1,tot); update(r[root]); update(root); } void Delete(int pos,int tot) { splay(find(pos),0); splay(find(pos+tot+1),root); recycle(l[r[root]]); l[r[root]]=0; update(r[root]); update(root); } void Make(int pos,int tot,int val) { splay(find(pos),0); splay(find(pos+tot+1),root); make_same(l[r[root]],val); update(r[root]); update(root); } void Reverse(int pos,int tot) { splay(find(pos),0); splay(find(pos+tot+1),root); reverse(l[r[root]]); update(r[root]); update(root); } int Get_sum(int pos,int tot) { splay(find(pos),0); splay(find(pos+tot+1),root); return sum[l[r[root]]]; } int Max_sum() { return maxs[root]; } void build(int &x,int fa,int L,int R) { if(L>R) {x=0; return;} x=newnode(); f[x]=fa; same[x]=inf; rev[x]=0; int mid=(L+R)/2; build(l[x],x,L,mid-1); scanf("%d",&v[x]); build(r[x],x,mid+1,R); update(x); } void init(int n) { v[0]=v[1]=v[2]=maxs[0]=-inf; same[1]=same[2]=inf; r[1]=2; f[2]=1; s[1]=2; s[2]=1; root=1; update(2); update(1); for(int i=3;i<maxn;i++) q[t++]=i; build(l[r[root]],r[root],1,n); update(r[root]); update(root); } /*void debug(int x) { if(!x) return; //push(x); debug(l[x]); printf("%d ",v[x]); debug(r[x]); }*/ }splay; char op[20]; int n,m,val,tot,pos; int main() { scanf("%d%d",&n,&m); splay.init(n); while(m--) { //splay.debug(splay.root); scanf("%s",op); if(op[0]==‘I‘) { scanf("%d%d",&pos,&tot); splay.Insert(pos,tot); } else if(op[0]==‘D‘) { scanf("%d%d",&pos,&tot); splay.Delete(pos,tot); } else if(op[0]==‘M‘ && op[2]==‘K‘) { scanf("%d%d%d",&pos,&tot,&val); splay.Make(pos,tot,val); } else if(op[0]==‘R‘) { scanf("%d%d",&pos,&tot); splay.Reverse(pos,tot); } else if(op[0]==‘G‘) { scanf("%d%d",&pos,&tot); printf("%d\n",splay.Get_sum(pos,tot)); } else { printf("%d\n",splay.Max_sum()); } } return 0; }
以上是关于bzoj1500: [NOI2005]维修数列的主要内容,如果未能解决你的问题,请参考以下文章