[BZOJ 1500]维修数列 [Splay Tree从进阶到住院]
2017-07-24 11:43
190 查看
历尽艰辛终于A掉了这题QwQ
贴COGS评论区几句话=.=
策爷:“splay/块状链表的自虐题。”。深刻理解到如果没有M倾向就不要去写这题了。。
-Chenyao2333
记得byvoid的博客上说这个题他当时写了整整一天,
我大约写了8个小时?
这种长代码程序结构一定要简单简单再简单,否则就是无限的调试了
-QhelDIV
这道题太恶心辣
一定要处理好哨兵节点和null节点的数据,update时要注意!
【没有用哨兵节点的请随意
-wumingshi
这题确实恶心还特喵的是个板子...
用Splay写的话思路非常明确,但是必须处理好两边的虚拟结点和空结点的标记值...(猝不及防的细节题...?)
算了算了先贴题面
Submit: 14422 Solved: 4692
Backup
然后该放图了来着w
贴COGS评论区几句话=.=
策爷:“splay/块状链表的自虐题。”。深刻理解到如果没有M倾向就不要去写这题了。。
-Chenyao2333
记得byvoid的博客上说这个题他当时写了整整一天,
我大约写了8个小时?
这种长代码程序结构一定要简单简单再简单,否则就是无限的调试了
-QhelDIV
这道题太恶心辣
一定要处理好哨兵节点和null节点的数据,update时要注意!
【没有用哨兵节点的请随意
-wumingshi
这题确实恶心还特喵的是个板子...
用Splay写的话思路非常明确,但是必须处理好两边的虚拟结点和空结点的标记值...(猝不及防的细节题...?)
算了算了先贴题面
1500: [NOI2005]维修数列
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 14422 Solved: 4692
Description
/************************************** Judge Result: Accepted **************************************/ #include <cstdio> #include <vector> #include <cstring> #include <cstring> #include <iostream> #include <algorithm> #define lch chd[0] #define rch chd[1] #define kch chd[k] #define xch chd[k^1] const int INF=0x2FFFFFFF; class SplayTree{ private: struct Node{ int k; int sz; int sm; int lm; int rm; int ms; bool set; bool rev; Node* prt; Node* chd[2]; Node(const int& key){ this->k=key; this->sm=key; this->ms=key; this->lm=key>=0?key:0; this->rm=key>=0?key:0; this->sz=1; this->prt=NULL; this->lch=NULL; this->rch=NULL; this->rev=false; this->set=false; } ~Node(){ if(this->lch!=NULL) delete this->lch; if(this->rch!=NULL) delete this->rch; } inline void Maintain(){ if(this!=NULL){ this->sz=this->lch->size()+this->rch->size()+1; this->sm=this->lch->sum()+this->rch->sum()+this->k; this->lm=std::max(this->lch->lmax(),this->lch->sum()+this->k+this->rch->lmax()); this->rm=std::max(this->rch->rmax(),this->rch->sum()+this->k+this->lch->rmax()); this->ms=std::max(std::max(this->lch->maxSum(),this->rch->maxSum()),this->lch->rmax()+this->k+this->rch->lmax()); } } inline void Swap(){ if(this!=NULL){ this->rev=!this->rev; std::swap(this->lm,this->rm); std::swap(this->lch,this->rch); } } inline void Set(const int& key){ if(this!=NULL){ this->set=true; this->k=key; this->sm=key*this->sz; this->lm=std::max(this->sm,0); this->rm=std::max(this->sm,0); this->ms=std::max(this->sm,this->k); } } inline void PushDown(){ if(this->set){ this->set=this->rev=false; this->lch->Set(this->k); this->rch->Set(this->k); } if(this->rev){ this->rev=false; this->lch->Swap(); this->rch->Swap(); } } inline int sum(){ return this==NULL?0:this->sm; } inline int maxSum(){ return this==NULL?-INF:this->ms; } inline int key(){ return this==NULL?0:this->k; } inline int lmax(){ return this==NULL?0:this->lm; } inline int rmax(){ return this==NULL?0:this->rm; } inline int size(){ return this==NULL?0:this->sz; } }*root; inline void Rotate(Node* root,int k){ Node* tmp=root->xch; root->PushDown(); tmp->PushDown(); tmp->prt=root->prt; if(root->prt==NULL) this->root=tmp; else if(root->prt->lch==root) root->prt->lch=tmp; else root->prt->rch=tmp; root->xch=tmp->kch; if(tmp->kch!=NULL) tmp->kch->prt=root; tmp->kch=root; root->prt=tmp; root->Maintain(); tmp->Maintain(); } void Splay(Node* root,Node* prt=NULL){ while(root->prt!=prt){ int k=root->prt->lch==root; if(root->prt->prt==prt){ Rotate(root->prt,k); } else{ int d=root->prt->prt->lch==root->prt; Rotate(k==d?root->prt->prt:root->prt,k); Rotate(root->prt,d); } } } Node* Build(const std::vector<int>& v,int l,int r){ if(l>r) return NULL; int mid=(l+r)>>1; Node* tmp=new Node(v[mid]); tmp->lch=Build(v,l,mid-1); tmp->rch=Build(v,mid+1,r); if(tmp->lch!=NULL) tmp->lch->prt=tmp; if(tmp->rch!=NULL) tmp->rch->prt=tmp; tmp->Maintain(); return tmp; } void PrintTree(Node* root,int deep){ for(int i=0;i<deep;i++) fputc(' ',stderr); fprintf(stderr, "(root=0x%X,key=%d,sum=%d,size=%d,lmax=%d,rmax=%d,maxSum=%d)\n", root,root->key(),root->sum(),root->size(),root->lmax(),root->rmax(),root->maxSum()); if(root==NULL) return; PrintTree(root->lch,deep+1); PrintTree(root->rch,deep+1); } public: SplayTree(){ this->root=new Node(-INF); this->root->rch=new Node(-INF); this->root->rch->prt=this->root; } SplayTree(const std::vector<int>& v){ this->root=Build(v,0,v.size()-1); } ~SplayTree(){ delete this->root; } Node* Kth(int pos){ ++pos; Node* root=this->root; while(root!=NULL){ root->PushDown(); int k=root->lch->size()+1; if(pos<k) root=root->lch; else if(pos==k) return root; else{ pos-=k; root=root->rch; } } return NULL; } inline int Sum(const int& pos,const int& len){ this->Splay(this->Kth(pos-1)); this->Splay(this->Kth(pos+len),this->root); return this->root->rch->lch->sum(); } inline void Reverse(const int& pos,const int& len){ this->Splay(this->Kth(pos-1)); this->Splay(this->Kth(pos+len),this->root); this->root->rch->lch->Swap(); this->root->rch->Maintain(); this->root->Maintain(); } inline void Set(const int& pos,const int& len,const int& d){ this->Splay(this->Kth(pos-1)); this->Splay(this->Kth(pos+len),this->root); this->root->rch->lch->Set(d); this->root->rch->Maintain(); this->root->Maintain(); } inline void Insert(const int& pos,SplayTree* data){ this->Splay(this->Kth(pos)); this->Splay(this->Kth(pos+1),this->root); Node* tmp=data->root; data->root=NULL; this->root->rch->lch=tmp; tmp->prt=this->root->rch; this->root->rch->Maintain(); this->root->Maintain(); } inline void Delete(const int& pos,const int& len){ this->Splay(this->Kth(pos-1)); this->Splay(this->Kth(pos+len),this->root); delete this->root->rch->lch; this->root->rch->lch=NULL; this->root->rch->Maintain(); this->root->Maintain(); } inline int MaxSum(){ return this->root->maxSum(); } void Print(){ this->PrintTree(this->root,0); } }; int FastRead(); int main(){ SplayTree* tree=new SplayTree(); std::vector<int> v; int n=FastRead(); int m=FastRead(); int a,b; char buf[20]; for(int i=0;i<n;i++){ v.push_back(FastRead()); } tree->Insert(0,new SplayTree(v)); for(int i=0;i<m;i++){ scanf("%s",buf); if(*buf!='M'||buf[2]!='X'){ a=FastRead(); b=FastRead(); } if(*buf=='G'){ printf("%d\n",tree->Sum(a,b)); } else if(*buf=='D') tree->Delete(a,b); else if(*buf=='R') tree->Reverse(a,b); else if(*buf=='I'){ v.clear(); while(b--) v.push_back(FastRead()); tree->Insert(a,new SplayTree(v)); } else if(*buf=='M'){ if(buf[2]=='K') tree->Set(a,b,FastRead()); else printf("%d\n",tree->MaxSum()); } // tree->Print(); } return 0; } int FastRead(){ int ans=0; bool neg=false; register char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') neg=true; ch=getchar(); } while(isdigit(ch)){ ans=ans*10+ch-'0'; ch=getchar(); } if(neg) ans=-ans; return ans; }
Backup
然后该放图了来着w
相关文章推荐
- BZOJ1500 [NOI2005]维修数列(Splay tree)
- BZOJ 1500: [NOI2005]维修数列 (splay tree)
- bzoj 1500 NOI2005 维修数列 [Splay]
- BZOJ 1500 NOI2005 维修数列 Splay
- 【BZOJ1500】[NOI2005]维修数列 Splay
- [bzoj1500 维修数列](NOI2005) (splay)
- BZOJ1500: [NOI2005]维修数列 [splay序列操作]【学习笔记】
- BZOJ1500 维修数列
- 【bzoj1500】[NOI2005]维修数列 Splay
- 【BZOJ】1500: [NOI2005]维修数列(splay+变态题)
- BZOJ 1500: [NOI2005]维修数列 splay
- BZOJ1500维修数列Splay
- BZOJ-1500 [NOI2005]维修数列
- BZOJ 1500: [NOI2005] 维修数列
- bzoj1500 [NOI2005]维修数列解题报告
- [Splay] BZOJ1500: [NOI2005]维修数列
- bzoj-1500 维修数列
- [bzoj1500][NOI2005]维修数列
- BZOJ 1500 [NOI 2005] 维修数列 (splay 模板)
- [BZOJ1500][NOI2005]维修数列