cogs 347 地震 splay
Posted Loser Of Life
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cogs 347 地震 splay相关的知识,希望对你有一定的参考价值。
链接:http://cogs.pro/cogs/problem/problem.php?pid=347
题意:不断维护一个区间,要求支持的操作有:删除区间、插入区间、区间加减、查询区间最大值。
看到这个题我们直接想到splay。还是熟悉的老方法,事先建两个节点,每一次操作,不管属于任何一种操作,先将区间的右端点转到右儿子,左端点转到根节点3号孙子,即右儿子的左儿子处。
1、区间加减:直接修改,延迟标记。
2、区间删除:直接扔掉左边界对应节点即可。
3、查询:基本操作。
4、插入区间:首先找到该区间位置,然后用初始建树相同方法插入即可。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<vector> 5 #define lch ch[0] 6 #define rch ch[1] 7 #define kch ch[k] 8 #define xch ch[k^1] 9 using namespace std; 10 inline int read() 11 { char c=getchar();int x=0,y=1; 12 while(c<‘0‘||c>‘9‘){if(c==‘-‘) y=-1;c=getchar();} 13 while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar(); 14 return x*y; 15 } 16 int inf=0x7fffffff,n,q; 17 class splay 18 { private: 19 struct node 20 { int k,s,h,lazy; 21 node* pt,*ch[2]; 22 node(const int& key) 23 { this->k=key;this->s=1;this->lazy=0; 24 this->lch=NULL;this->rch=NULL; 25 } 26 inline int sz(){return this?this->s:0;} 27 inline int key(){return this?this->k:0;} 28 inline int qh(){return this?this->h:-inf;} 29 ~node() 30 { if(this->lch) delete this->lch; 31 if(this->rch) delete this->rch; 32 } 33 inline void mt() 34 { if(this) this->s=this->lch->sz()+this->rch->sz()+1; 35 if(this) this->h=std::max(this->k,max(this->lch->qh(),this->rch->qh())); 36 } 37 inline void dn() 38 { if(this&&this->lazy) 39 { if(lch) lch->lazy+=lazy,lch->k+=lazy,lch->h+=lazy; 40 if(rch) rch->lazy+=lazy,rch->k+=lazy,rch->h+=lazy; 41 lazy=0; 42 } 43 } 44 inline void Ad(int key){if(this){this->lazy+=key;this->k+=key;this->h+=key;}} 45 inline int pos(){return this==this->pt->lch;} 46 }*root; 47 void rotate(node* rt,int k) 48 { node* tmp=rt->xch; 49 rt->dn();tmp->dn(); 50 tmp->pt=rt->pt; 51 if(!rt->pt) this->root=tmp; 52 else if(rt->pt->lch==rt) rt->pt->lch=tmp; 53 else rt->pt->rch=tmp; 54 rt->xch=tmp->kch; 55 if(tmp->kch) tmp->kch->pt=rt; 56 tmp->kch=rt;rt->pt=tmp; 57 rt->mt();tmp->mt(); 58 } 59 void sp(node* rt,node* prt=NULL) 60 { while(rt->pt!=prt) 61 { int k=rt->pt->lch==rt; 62 if(rt->pt->pt==prt) rotate(rt->pt,k); 63 else 64 { int d=rt->pt->pt->lch==rt->pt; 65 rotate(k==d?rt->pt->pt:rt->pt,k); 66 rotate(rt->pt,d); 67 } 68 } 69 } 70 node* build(const std::vector<int>& v,int l,int r) 71 { if(l>r) return NULL; 72 int mid=(l+r)>>1;node* tmp=new node(v[mid]); 73 tmp->lch=build(v,l,mid-1);tmp->rch=build(v,mid+1,r); 74 if(tmp->lch) tmp->lch->pt=tmp; if(tmp->rch) tmp->rch->pt=tmp; 75 tmp->mt(); 76 return tmp; 77 } 78 public: 79 ~splay(){delete this->root;} 80 splay(const std::vector<int>& v){this->root=build(v,0,v.size()-1);} 81 splay(){this->root=new node(-inf);this->root->rch=new node(-inf);this->root->rch->pt=this->root;} 82 node* kth(int x) 83 { ++x; 84 node* now=this->root; 85 while(now!=NULL) 86 { now->dn(); 87 int k=now->lch->sz()+1; 88 if(x<k) now=now->lch; 89 else if(x==k) return now; 90 else x-=k,now=now->rch; 91 } 92 return NULL; 93 } 94 void add(int x,int y,int z) 95 { node* tmp=this->kth(y+1),*tmp2=this->kth(x-1); 96 this->sp(tmp2);this->sp(tmp,this->root); 97 this->root->rch->lch->Ad(z); 98 this->root->rch->mt();this->root->mt(); 99 } 100 void del(int x,int y) 101 { node* tmp=this->kth(y+1),*tmp2=this->kth(x-1); 102 this->sp(tmp2);this->sp(tmp,this->root); 103 delete this->root->rch->lch; 104 this->root->rch->lch=NULL; 105 this->root->rch->mt();this->root->mt(); 106 } 107 int hmax(int x,int y) 108 { node* tmp=this->kth(y+1),*tmp2=this->kth(x-1); 109 this->sp(tmp2);this->sp(tmp,this->root); 110 return this->root->rch->lch->h; 111 } 112 void insert(int x,splay* data) 113 { this->sp(this->kth(x));this->sp(this->kth(x+1),this->root); 114 node* tmp=data->root;data->root=NULL; 115 this->root->rch->lch=tmp;tmp->pt=this->root->rch; 116 this->root->rch->mt();this->root->mt(); 117 } 118 }; 119 int main() 120 { freopen("equake.in","r",stdin); 121 freopen("equake.out","w",stdout); 122 n=read();q=read(); 123 splay* tree=new splay(); 124 std::vector<int>v;char ord[10];int x,y,z; 125 for(int i=1;i<=n;i++) v.push_back(read()); 126 tree->insert(0,new splay(v)); 127 for(int i=1;i<=q;i++) 128 { scanf("%s",ord); 129 if(ord[0]==‘R‘){x=read();y=read();z=read();tree->add(x,y,z);} 130 if(ord[0]==‘I‘) 131 { v.clear();x=read();y=read(); 132 while(y--) v.push_back(read()); 133 tree->insert(x,new splay(v)); 134 } 135 if(ord[0]==‘M‘){x=read();y=read();tree->del(x,y);} 136 if(ord[0]==‘Q‘){x=read();y=read();printf("%d\n",tree->hmax(x,y));} 137 } 138 return 0; 139 }
以上是关于cogs 347 地震 splay的主要内容,如果未能解决你的问题,请参考以下文章
数据结构(Splay平衡树):COGS 339. [NOI2005] 维护数列
COGS 74. [NOIP2006] 明明的随机数 (Splay小练习。。)