您的位置:首页 > 其它

[BZOJ 1500]维修数列 [Splay Tree从进阶到住院]

2017-07-24 11:43 190 查看
历尽艰辛终于A掉了这题QwQ

贴COGS评论区几句话=.=


策爷:“splay/块状链表的自虐题。”。深刻理解到如果没有M倾向就不要去写这题了。。

  -Chenyao2333



记得byvoid的博客上说这个题他当时写了整整一天,
我大约写了8个小时?
这种长代码程序结构一定要简单简单再简单,否则就是无限的调试了

  -QhelDIV



这道题太恶心辣
一定要处理好哨兵节点和null节点的数据,update时要注意!
【没有用哨兵节点的请随意

   -wumingshi


这题确实恶心还特喵的是个板子...

用Splay写的话思路非常明确,但是必须处理好两边的虚拟结点和空结点的标记值...(猝不及防的细节题...?)

算了算了先贴题面

1500: [NOI2005]维修数列

Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: