初识splay tree (一)
来源:互联网 发布:苏联解体中国反应 知乎 编辑:程序博客网 时间:2024/06/04 18:29
本来是要做hihocoder 1034 毁灭者问题,发现朴素的数据结构无法满足该题目如此BT的要求,随查了一下,splay tree貌似可以解决,于是目标转到了学习splay tree上。
学习splay tree 的主要参考资料:
《伸展树的基本操作与应用》– 杨思雨
《运用伸展树解决数列维护问题》– By Crash
《Splaying a Search Tree in Preorder Takes Linear Time》
《NOI 2005 维护数列》– ByVoid
《NOI 2005 维护数列 测试数据》
太晚了,具体操作原理、细节明天再更新。。
这里先发一个poj3468 A Simple Problem with Integers AC代码,当做初学splay tree的第一道测试题。
#include <iostream>#include <cstdio>#include <cstdlib>using namespace std;#define ll64 long long int struct st{ struct node{ long long int size,value,cover,sums; struct node *pre,*ch[2]; }; node *nill,*root; node buf[200000]; int bufsize; int pushdown(node *x){ if(x==nill || x==NULL) return 0; if(x->cover){ x->value+=x->cover; x->sums+=x->cover*x->size; x->ch[0]->cover+=x->cover; x->ch[1]->cover+=x->cover; x->cover=0; } return 0; } int update(node *x){ if(x==nill || x==NULL) return 0; pushdown(x->ch[0]);pushdown(x->ch[1]); x->size = x->ch[0]->size+x->ch[1]->size+1; x->sums=x->ch[0]->sums+x->ch[1]->sums+x->value; return 0; } node *getnode(ll64 value,node *fa){ node *p=buf+bufsize++; p->cover=0; p->value=p->sums=value; p->size=1; p->ch[0]=p->ch[1]=nill; p->pre=fa; return p; } int init(){ bufsize=0; nill=root=NULL; nill=getnode(0,NULL); nill->size=0; nill->ch[0]=nill->ch[1]=NULL; root=getnode(0,nill); root->ch[1]=getnode(0,root); return 0; } int rotateto(node*x,int to){ node *y=x->pre; y->ch[to^1]=x->ch[to]; y->ch[to^1]->pre=y; x->pre=y->pre; if(y==y->pre->ch[0])x->pre->ch[0]=x; else x->pre->ch[1]=x; x->ch[to]=y; y->pre=x; update(y); if(y==root) root=x; return 0; } int splay(node *x,node *fa){ pushdown(x); while(x->pre!=fa ){ if(x->pre->pre==fa){ if(x->pre->ch[0]==x) rotateto(x,1); else rotateto(x,0); }else{ if(x->pre->pre->ch[0]==x->pre){ if(x->pre->ch[0]==x){rotateto(x->pre,1);rotateto(x,1);} else{rotateto(x,0);rotateto(x,1);} }else{ if(x->pre->ch[0]==x){rotateto(x,1);rotateto(x,0);} else{rotateto(x->pre,0);rotateto(x,0);} } } } update(x); return 0; } int select(int k,node *fa){ node *rt=root; while(rt!=nill){ pushdown(rt); if(rt->ch[0]->size == k-1) break; else if(rt->ch[0]->size>k-1) rt=rt->ch[0]; else {k-=rt->ch[0]->size+1; rt=rt->ch[1];} } splay(rt,fa); return 0; } int insert(int pos,int tot){ node *p,*q; long long int s; scanf("%lld",&s); p=q=getnode(s,nill); for(int i=1;i<tot;i++){ scanf("%lld",&s); p=p->ch[1]=getnode(s,p); } select(pos+1,nill); select(pos+2,root); root->ch[1]->ch[0]=q; q->pre=root->ch[1]; splay(p,nill); return 0; } int add(int a,int b,long long int c){ select(a,nill); select(b+2,root); root->ch[1]->ch[0]->cover+=c; splay(root->ch[1]->ch[0],nill); return 0; } ll64 getsums(int a,int b){ select(a,nill); select(b+2,root); // cout<<root->value<<" "<<root->ch[1]->value<<endl; pushdown(root->ch[1]->ch[0]); return root->ch[1]->ch[0]->sums; }};int main(){ int n,q; scanf("%d %d",&n,&q); st *str=new st; str->init(); str->insert(0,n); char s[10]; ll64 c; int a,b; for(int i=0;i<q;i++){ scanf("%s %d %d",s,&a,&b); //cout<<s<<" "<<a<<" "<<b<<endl; if(s[0]=='Q'){ printf("%lld\n",str->getsums(a,b)); }else{ scanf("%lld",&c); str->add(a,b,c); } } return 0;}
同时还查到了一个有意思的问题,在这里记下:
《动态树问题及其应用》
0 0
- 初识splay tree (一)
- 初识splay tree (二)
- 初识splay tree (三)
- bzoj1208(splay tree)
- splay tree(伸展树)学习小结(一)
- 初识splay tree ( hihocoder #1034 : 毁灭者问题 题解)
- 伸展树( splay tree)
- Splay Tree(伸展树)
- 伸展树(splay tree)
- 伸展树(Splay Tree)
- 伸展树(Splay tree)
- Splay Tree
- splay tree
- Splay Tree
- Splay Tree
- splay tree
- Splay tree
- splay tree
- struts2小结
- 实时技术
- hdu5217Brackets【线段树,二分】
- Cheating sheet for vim
- 解题报告 之 SOJ2666 分解 n!
- 初识splay tree (一)
- 2015年的春天——我在北京
- 谈一下使用akamai media on demand no secure 遇到的问题和解决经历
- 基于Redis实现分布式消息队列(1)
- YII CRUD [ 2.0 版本 ] 与教程地址
- avahi-daemon
- 关于android中drawable文件夹下各类xml样式文件的使用详解
- Dynamics AX 配置 SANA,录入SANA基础数据
- [转]SSH三大框架的工作原理及流程