BZOJ1500: [NOI2005]维修数列
2017-02-15 08:14
501 查看
传送门
写完这道题后我有一句妈卖批不知道当不当讲?
具体的怎么操作大家都很容易脑补出来,简单说几点需要注意的:
1.赋初值的时候注意把t[0].mx设为-oo,以及0节点和N+1节点。
2.每次对对应的区间操作完后注意进行两次reload
3.每个节点的lx与rx可以为0,所以mx不可以对lx与rx取max。
4.对于区间翻转后不能立刻在当前区间进行reload,注意交换lx与rx。
5.fix如果为负值的话mx应该为val而不是sum
6.注意回收内存
写完这道题后我有一句妈卖批不知道当不当讲?
具体的怎么操作大家都很容易脑补出来,简单说几点需要注意的:
1.赋初值的时候注意把t[0].mx设为-oo,以及0节点和N+1节点。
2.每次对对应的区间操作完后注意进行两次reload
3.每个节点的lx与rx可以为0,所以mx不可以对lx与rx取max。
4.对于区间翻转后不能立刻在当前区间进行reload,注意交换lx与rx。
5.fix如果为负值的话mx应该为val而不是sum
6.注意回收内存
//BZOJ1500 //by Cydiater //2017.2.14 #include <iostream> #include <queue> #include <map> #include <cstring> #include <string> #include <algorithm> #include <cstdlib> #include <cstdio> #include <iomanip> #include <cmath> #include <ctime> #include <bitset> #include <set> #include <vector> #include <complex> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) #define FILE "seq2005" const int MAXN=5e5+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();int x=0,f=1; while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int N,M,arr[MAXN]; int top=0,cnt=0,root=0; struct SplayTree{ int son[2],lx,rx,mx,siz,val,sum,fa,tag,fix; }t[MAXN]; char s[MAXN]; queue<int>Q; namespace solution{ inline int get(int k){return t[t[k].fa].son[1]==k;} inline void reload(int k){ int s1=t[k].son[0],s2=t[k].son[1]; t[k].sum=t[s1].sum+t[s2].sum+t[k].val; t[k].siz=t[s1].siz+t[s2].siz+1; t[k].mx=max(t[s1].mx,t[s2].mx); cmax(t[k].mx,t[s1].rx+t[k].val+t[s2].lx); t[k].lx=max(t[s1].lx,t[s1].sum+t[k].val+t[s2].lx); t[k].rx=max(t[s2].rx,t[s2].sum+t[k].val+t[s1].rx); } inline void rotate(int k){ int old=t[k].fa,oldf=t[old].fa,which=get(k); t[old].son[which]=t[k].son[which^1];t[t[old].son[which]].fa=old; t[old].fa=k;t[k].son[which^1]=old; t[k].fa=oldf; if(oldf)t[oldf].son[t[oldf].son[1]==old]=k; reload(old);reload(k); } void Pushdown(int k){ int s1=t[k].son[0],s2=t[k].son[1]; if(t[k].fix!=1001){ int fix=t[k].fix; t[k].fix=1001; if(s1){ t[s1].val=t[s1].fix=fix; t[s1].sum=t[s1].siz*fix; if(fix>=0)t[s1].lx=t[s1].rx=t[s1].mx=t[s1].sum; else{ t[s1].lx=t[s1].rx=0; t[s1].mx=fix; } } if(s2){ t[s2].val=t[s2].fix=fix; t[s2].sum=t[s2].siz*fix; if(fix>=0)t[s2].lx=t[s2].rx=t[s2].mx=t[s2].sum; else{ t[s2].lx=t[s2].rx=0; t[s2].mx=fix; } } } if(t[k].tag){ if(s1)t[s1].tag^=1;if(s2)t[s2].tag^=1; swap(t[s1].son[0],t[s1].son[1]); swap(t[s1].lx,t[s1].rx); swap(t[s2].son[0],t[s2].son[1]); swap(t[s2].lx,t[s2].rx); t[k].tag=0; } } inline void splay(int k,int aim){ for(int fa;(fa=t[k].fa);rotate(k)){ if(k==aim)break; else if(fa==aim){ rotate(k); break; }else if(t[fa].fa==aim){ rotate(get(fa)==get(k)?fa:k); rotate(k); break; }else rotate(get(fa)==get(k)?fa:k); } if(aim==root)root=k; } void Build(int L,int R,int &k,int fa){ if(!k){ k=Q.front(); Q.pop(); } int mid=(L+R)>>1; t[k].fa=fa;t[k].val=arr[mid];t[k].siz=1;t[k].fix=1001; if(L==R){ t[k].son[0]=t[k].son[1]=0; t[k].lx=t[k].rx=t[k].sum=t[k].mx=t[k].val; cmax(t[k].lx,0); cmax(t[k].rx,0); return; } if(L<=mid-1)Build(L,mid-1,t[k].son[0],k); if(mid+1<=R)Build(mid+1,R,t[k].son[1],k); reload(k); } int rnk(int rank){ int now=root; while(rank){ Pushdown(now); int lsiz=t[now].son[0]?t[t[now].son[0]].siz:0; if(rank>lsiz){ if(rank==lsiz+1)return now; rank-=lsiz+1; now=t[now].son[1]; }else now=t[now].son[0]; } return now; } void Match(int L,int R){ int kl=rnk(L),kr=rnk(R+2); splay(kl,root);splay(kr,t[root].son[1]); } void Rec(int now){ Q.push(now); if(t[now].son[0])Rec(t[now].son[0]); if(t[now].son[1])Rec(t[now].son[1]); t[now].son[0]=t[now].son[1]=t[now].lx=t[now].mx=t[now].rx=t[now].sum=t[now].siz=t[now].val=t[now].tag=0; t[now].fix=1001; } void Insert(int pos,int tol){ Match(pos+1,pos); up(i,1,tol)arr[i]=read(); int rt=0,tmp=t[root].son[1]; Build(1,tol,rt,t[tmp].son[0]); t[tmp].son[0]=rt; t[rt].fa=tmp; reload(tmp); reload(t[tmp].fa); } void Del(int pos,int tol){ int L=pos,R=pos+tol-1; Match(L,R); int tmp=t[root].son[1]; Rec(t[tmp].son[0]); t[tmp].son[0]=0; reload(tmp); reload(t[tmp].fa); } void Fix(int pos,int tol){ int L=pos,R=pos+tol-1; Match(L,R); int tmp=t[t[root].son[1]].son[0]; t[tmp].fix=t[tmp].val=read(); t[tmp].sum=t[tmp].siz*t[tmp].val; t[tmp].lx=max(0,t[tmp].siz*t[tmp].val); t[tmp].rx=t[tmp].lx; t[tmp].mx=max(t[tmp].val,t[tmp].sum); reload(t[tmp].fa); reload(root); } void Rev(int pos,int tol){ int L=pos,R=pos+tol-1; Match(L,R); int tmp=t[t[root].son[1]].son[0]; if(t[tmp].fix==1001){ t[tmp].tag^=1; swap(t[tmp].son[0],t[tmp].son[1]); swap(t[tmp].lx,t[tmp].rx); reload(t[tmp].fa); reload(root); } } int Sum(int pos,int tol){ int L=pos,R=pos+tol-1; Match(L,R); return t[t[t[root].son[1]].son[0]].sum; } void Prepare(){ N=read();M=read(); up(i,1,500000)Q.push(i); up(i,1,N)arr[i]=read(); arr[0]=arr[N+1]=t[0].mx=-oo; Build(0,N+1,root,0); } void Solve(){ while(M--){ scanf("%s",s); int pos,tol; if(s[0]!='M'||s[2]!='X'){pos=read();tol=read();} if(s[0]=='I')Insert(pos,tol); else if(s[0]=='D')Del(pos,tol); else if(s[0]=='M'&&s[2]=='K')Fix(pos,tol); else if(s[0]=='R')Rev(pos,tol); else if(s[0]=='G') printf("%d\n",Sum(pos,tol)); else printf("%d\n",t[root].mx); } } } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); using namespace solution; Prepare(); Solve(); return 0; }
相关文章推荐
- BZOJ 1500 [NOI2005]维修数列 (splay)
- BZOJ 1500([NOI2005]维修数列-Splay的数列维护)
- 【bzoj1500】[NOI2005]维修数列
- bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)
- bzoj:1500: [NOI2005]维修数列
- [bzoj1500][NOI2005]维修数列——splay
- bzoj 1500 [NOI 2005] 维修数列
- BZOJ1500: [NOI2005]维修数列 Splay
- 【BZOJ1500】【NOI2005】维修数列
- [BZOJ1500][NOI2005][Splay]维修数列
- 【bzoj1500】[NOI2005]维修数列 Splay
- BZOJ 1500 [NOI2005]维修数列(splay)
- [BZOJ 1500][NOI2005]维修数列(Splay)
- [bzoj1500][NOI2005]维修数列
- bzoj1500 [NOI2005]维修数列解题报告
- BZoj 1500 [NOI2005]维修数列 (Splay 模板)
- [BZOJ1500][NOI2005]维修数列
- 【BZOJ1500】【NOI2005】维修数列(Splay)
- [BZOJ1500][NOI2005]维修数列
- 【bzoj1500】[NOI2005]维修数列 Splay