[BZOJ]1500 维修数列
2017-07-25 14:00
246 查看
1500: [NOI2005]维修数列
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 14433 Solved: 4701
[Submit][Status][Discuss]
Description
Input
输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
Output
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。Sample Input
9 82 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
Sample Output
-110
1
10
HINT
Source
[Submit][Status][Discuss]
HOME Back
终于A掉这道题了,调了快一个小时...splay有个地方写错了导致rotate着的时候有一个儿子掉了...其他就没什么好说的,因为这道题是splay裸题,算是代码题(其实也不算太长).看一下代码的update就能懂了怎么求最大子段和了.
纪念一下:
RunID | User | Problem | Result | Memory | Time | Language | Code_Length | Submit_Time |
2186510 | MaxMercer | 1500 | Accepted | 28184 kb | 4360 ms | C++/Edit | 5492 B | 2017-07-25 10:45:55 |
#include<stdio.h> #include<algorithm> using namespace std; const int inf=(1<<29); const int maxn=500005; char ss[20]; int n,T,newone,tot,a[maxn],rev[maxn],tag[maxn],w[maxn],s[maxn],root; int _recycle[maxn],_recycle_top,c[maxn][2],fa[maxn],siz[maxn],sum[maxn],lmax[maxn],rmax[maxn],ans[maxn]; inline const int read(){ register int f=1,x=0; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return f*x; } inline int newnode(){ if(_recycle_top) newone=_recycle[_recycle_top--]; else newone=++tot; c[newone][0]=c[newone][1]=fa[newone]=0; rev[newone]=tag[newone]=0,siz[newone]=1; lmax[newone]=rmax[newone]=sum[newone]=w[newone]=-inf; return newone; } inline void reverse(int x){ if(!x) return; swap(lmax[x],rmax[x]); swap(c[x][0],c[x][1]); rev[x]^=1; } inline void replace(int x,int val){ w[x]=val;sum[x]=siz[x]*val; lmax[x]=rmax[x]=ans[x]=max(val,siz[x]*val); tag[x]=1; } inline void update(int x){ if(!x) return; siz[x]= siz[c[x][0]]+siz[c[x][1]]+1; sum[x]= sum[c[x][0]]+sum[c[x][1]]+w[x]; lmax[x]=max(lmax[c[x][0]],sum[c[x][0]]+w[x]+max(lmax[c[x][1]],0)); rmax[x]=max(rmax[c[x][1]],sum[c[x][1]]+w[x]+max(rmax[c[x][0]],0)); ans[x]= max(max(ans[c[x][0]],ans[c[x][1]]),max(rmax[c[x][0]],0)+w[x]+max(lmax[c[x][1]],0)); } inline void pushdown(int x){ if(rev[x]){ if(c[x][0]) reverse(c[x][0]); if(c[x][1]) reverse(c[x][1]); rev[x]=0; } if(tag[x]){ if(c[x][0]) replace(c[x][0],w[x]); if(c[x][1]) replace(c[x][1],w[x]); tag[x]=0; } } inline void rotate(int x,int &_wanna){ int y=fa[x],z=fa[y]; int l=(c[y][0]!=x),r=l^1; if(y!=_wanna) c[z][c[z][0]!=y]=x; else _wanna=x; fa[x]=z,fa[y]=x,fa[c[x][r]]=y; c[y][l]=c[x][r],c[x][r]=y; update(y),update(x); } inline void splay(int x,int &_wanna){ int top=0; s[++top]=x; for(int i=x;fa[i];i=fa[i]) s[++top]=fa[i]; for(int i=top;i;i--) pushdown(s[i]); for(int f;x!=_wanna;rotate(x,_wanna)) if((f=fa[x])!=_wanna) rotate(((c[f][1]==x^c[fa[f]][1]==f)?x:f),_wanna); } void build(int lf,int rg,int who){ int mid=(lf+rg)>>1; w[who]=a[mid]; if(lf==rg) {sum[who]=lmax[who]=rmax[who]=ans[who]=w[who];siz[who]=1;return;} if(lf<mid) {c[who][0]=newnode();fa[c[who][0]]=who;build(lf,mid-1,c[who][0]);} if(rg>mid) {c[who][1]=newnode();fa[c[who][1]]=who;build(mid+1,rg,c[who][1]);} update(who); } int find(int k,int x){ pushdown(k); if(x-1==siz[c[k][0]]) return k; else if(x>siz[c[k][0]]+1) return find(c[k][1],x-siz[c[k][0]]-1); else return find(c[k][0],x); } inline void Reverse(int x,int num){ x=find(root,x),splay(x,root); int y=find(c[x][1],num+1);splay(y,c[x][1]); reverse(c[y][0]); update(y),update(x); } inline void Replace(int x,int num,int z){ x=find(root,x),splay(x,root); int y=find(c[x][1],num+1);splay(y,c[x][1]); replace(c[y][0],z); update(y),update(x); } void erase(int x){ if(!x) return; _recycle[++_recycle_top]=x; if(c[x][0]) erase(c[x][0]); if(c[x][1]) erase(c[x][1]); } inline void del(int x,int num){ x=find(root,x),splay(x,root); int y=find(c[x][1],num+1);splay(y,c[x][1]); erase(c[y][0]); fa[c[y][0]]=c[y][0]=0; update(y),update(x); } inline void insert(int x,int num){ for(register int i=1;i<=num;i++) a[i]=read(); x=find(root,x+1),splay(x,root); int y=find(c[x][1],1);splay(y,c[x][1]); c[y][0]=newnode();fa[c[y][0]]=y; build(1,num,c[y][0]); update(y),update(x); } inline void init(){ n=read(),T=read(); for(register int i=1;i<=n;i++) a[i]=read(); lmax[0]=rmax[0]=ans[0]=-inf;root=1,tot=2; fa[1]=0,lmax[1]=rmax[1]=ans[1]=sum[1]=w[1]=-inf,c[1][1]=2,siz[1]=2; fa[2]=1,lmax[2]=rmax[2]=ans[2]=sum[2]=w[2]=-inf,fa[2]=1,siz[1]=1; c[2][0]=newnode(),fa[c[2][0]]=2,build(1,n,c[2][0]); update(2),update(1); } int main(){ init(); while(T--){ int x,y,z; scanf("%s",ss); if(ss[0]=='I'){ x=read(),y=read(); insert(x,y); } if(ss[0]=='D'){ x=read(),y=read(); del(x,y); } if(ss[4]=='-'){ x=read(),y=read(),z=read(); Replace(x,y,z); } if(ss[0]=='R'){ x=read(),y=read(); Reverse(x,y); } if(ss[0]=='G'){ x=read(),y=read(); x=find(root,x);splay(x,root); y=find(c[x][1],y+1);splay(y,c[x][1]); printf("%d\n",sum[c[y][0]]); } if(ss[2]=='X') printf("%d\n",ans[root]); } return 0; }
相关文章推荐
- bzoj1500 [NOI2005]维修数列
- 【splay】[noi2005] bzoj1500 维修数列
- BZOJ 1500: [NOI2005]维修数列
- [BZOJ 1500] [NOI2005] 维修数列
- [bzoj1500][NOI2005]维修数列 splay大模板
- 【bzoj1500】维修数列 splay
- [BZOJ1500][NOI2005]维修数列
- BZOJ1500 维修数列
- Bzoj1500 [NOI2005]维修数列
- bzoj1500维修数列splay
- BZOJ 1500 [NOI2005]维修数列 (splay)
- BZOJ 1500 [NOI2005]维修数列(splay)
- [BZOJ 1500]维修数列 [Splay Tree从进阶到住院]
- bzoj1500 [NOI2005]维修数列
- 【bzoj1500】[NOI2005]维修数列
- 【bzoj1500】[NOI2005]维修数列
- bzoj 1500 维修数列
- Splay 模板【NOI2005】 bzoj1500 维修数列
- 【BZOJ 1500】 维修数列|Splay
- [NOI2005] [BZOJ1500] 维修数列 - splay