P2710-数列【Splay】
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                P2710-数列【Splay】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                正題
題目鏈接:https://www.luogu.com.cn/problem/P2710
題目大意
nnn個(gè)數(shù),mmm次操作要求支持
解題思路
用SplaySplaySplay維護(hù),記錄lmaxlmaxlmax和rmaxrmaxrmax然后合并。要注意如果一個(gè)區(qū)間全是負(fù)數(shù)不能選空。
時(shí)間復(fù)雜度O(nlog?n)O(n\log n)O(nlogn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define max3(x,y,z) max(max((x),(y)),(z)) using namespace std; const int N=5e5+10,inf=2147483647/3; int n,m,tot,root,t[N][2],fa[N],r[N],lazy[N],val[N]; int lmax[N],rmax[N],sum[N],ans[N],siz[N]; void PushUp(int x){lmax[x]=max(lmax[t[x][0]],sum[t[x][0]]+val[x]+lmax[t[x][1]]);rmax[x]=max(rmax[t[x][1]],sum[t[x][1]]+val[x]+rmax[t[x][0]]);ans[x]=max3(ans[t[x][0]],ans[t[x][1]],rmax[t[x][0]]+val[x]+lmax[t[x][1]]);sum[x]=sum[t[x][0]]+sum[t[x][1]]+val[x];siz[x]=siz[t[x][0]]+siz[t[x][1]]+1;return; } void Change(int x,int z){if(!siz[x])siz[x]=1;val[x]=z;sum[x]=z*siz[x];if(z>0)lmax[x]=rmax[x]=ans[x]=sum[x];else lmax[x]=rmax[x]=0,ans[x]=z;return; } void rev(int x){swap(t[x][0],t[x][1]);swap(lmax[x],rmax[x]);r[x]^=1;return; } void PushDown(int x){if(lazy[x]!=-inf){if(t[x][0])Change(t[x][0],lazy[x]),lazy[t[x][0]]=lazy[x];if(t[x][1])Change(t[x][1],lazy[x]),lazy[t[x][1]]=lazy[x];lazy[x]=-inf;}if(r[x]){rev(t[x][0]);rev(t[x][1]);r[x]=0;}PushUp(x);return; } void DownData(int x){if(!x)return;DownData(fa[x]);PushDown(x);return; } bool Direct(int x) {return t[fa[x]][1]==x;} void Connect(int x,int y,int dir) {t[x][dir]=y;fa[y]=x;return;} void Rotate(int x){int y=fa[x],z=fa[fa[x]];int xs=Direct(x),ys=Direct(y);Connect(y,t[x][xs^1],xs);Connect(x,y,xs^1);Connect(z,x,ys);PushUp(y);PushUp(x);return; } void Splay(int x,int f){DownData(x);while(fa[x]!=f){int up=fa[x];if(fa[up]==f)Rotate(x);else if(Direct(x)==Direct(up))Rotate(up),Rotate(x);else Rotate(x),Rotate(x);}return; } int Find(int x,int k){PushDown(x);if(siz[t[x][0]]>=k)return Find(t[x][0],k);if(siz[t[x][0]]+1==k)return x;return Find(t[x][1],k-siz[t[x][0]]-1); } int Split(int l,int r){int x=Find(root,l),y=Find(root,r+2);Splay(x,0);Splay(y,x);root=x;return t[y][0]; } void write(int x){if(!x)return;write(t[x][0]);printf("%d ",val[x]);write(t[x][1]); } int main() {scanf("%d%d",&n,&m);ans[0]=-inf;for(int i=0;i<N;i++)lazy[i]=-inf;siz[1]=1;Change(1,-inf);for(int i=2;i<=n+1;i++){scanf("%d",&val[i]);Change(i,val[i]);t[i][0]=i-1;fa[i-1]=i;PushUp(i); }Change(n+2,-inf);t[n+2][0]=n+1;fa[n+1]=n+2;PushUp(n+2);root=tot=n+2;while(m--){char op[15];scanf("%s",op);if(op[0]=='I'){int x;scanf("%d%d",&x,&n);int l=Find(root,x+1),r=Find(root,x+2);Splay(l,0);Splay(r,l);int last=++tot;scanf("%d",&x);t[r][0]=tot;fa[tot]=r;Change(tot,x);for(int i=2;i<=n;i++){scanf("%d",&x);Change(++tot,x);t[tot-1][1]=tot;fa[tot]=tot-1;}for(int i=tot;i>=last;i--)PushUp(i);Splay(last,0);root=last;}else if(op[0]=='D'){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);t[fa[x]][0]=0;PushUp(fa[x]);PushUp(fa[fa[x]]);}else if(op[0]=='R'){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);rev(x);PushUp(fa[x]);PushUp(fa[fa[x]]);}else if(op[0]=='M'&&op[2]=='K'){int x,w;scanf("%d%d%d",&x,&n,&w);x=Split(x,x+n-1);Change(x,w);lazy[x]=w;PushUp(fa[x]);PushUp(fa[fa[x]]);}else if(op[0]=='G'&&strlen(op)==7){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);printf("%d\n",sum[x]); }else if(op[0]=='G'){int x;scanf("%d",&x);x=Split(x,x);printf("%d\n",val[x]);}else if(op[0]=='M'){int x;scanf("%d%d",&x,&n);x=Split(x,x+n-1);printf("%d\n",ans[x]);} // write(root);putchar('\n');} }總結(jié)
以上是生活随笔為你收集整理的P2710-数列【Splay】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 淦是什么意思梗出自哪 淦一开始出现在哪里
- 下一篇: 逶迤怎么读 逶迤的意思介绍
