fhq的 挖掘treap的潜力

来源:互联网 发布:女人舔屁眼知乎 编辑:程序博客网 时间:2024/05/16 18:18
http://fanhq666.blog.163.com/blog/static/819434262011021105212299/你的Treap能支持以下操作吗?1.区间增减2.区间求最小3.区间反转(倒序)4.区间移动(把一段剪切、粘贴)不能?只能用splay?其实,Treap也可以办到。方法就是:设计把一个子树split成两个子树的算法,以及把两个子树merge的算法。例:poj3580,代码见最后另外一个应用:可持久化Treap设计一个数据结构维护一个序列 插入一个元素 删除一个元素 移动连续的一段(就是剪切、粘贴) *查询m次操作之前的第p个元素是谁例:超级文本编辑器(我正在构思的一道题)文本长度不超过100000每次可以插入、删除、剪切粘贴要求在线算法每个操作10微秒时限,一共32M内存这个可以参见算法导论,核心思想是:一个节点创建之后就不再删除。另外用垃圾回收。
poj3580#include <cstdio>#include <algorithm>using namespace std;int ran(){static int x=1364684679;x+=(x<<2)+1;return x;}struct node{int k,mn,delta,mark,w,sz;node *l,*r;static node* getnew(node *w=NULL){static node *list=NULL;if (w){w->r=list;list=w;return NULL;}if (!list){node *q=new node[10000];for (int i=0;i<10000;i++){q[i].w=ran();q[i].r=list;list=q+i;}}node *p=list;list=list->r;p->l=p->r=NULL;p->delta=p->mark=0;return p;}void down(){if (mark){if (l)swap(l->l,l->r),l->mark^=1;if (r)swap(r->l,r->r),r->mark^=1;mark=0;}if (delta){if (l)l->mn+=delta,l->delta+=delta,l->k+=delta;if (r)r->mn+=delta,r->delta+=delta,r->k+=delta;delta=0;}}void update(){mn=k;if (l && mn>l->mn+delta)mn=l->mn+delta;if (r && mn>r->mn+delta)mn=r->mn+delta;sz=1;if (l)sz+=l->sz;if (r)sz+=r->sz;}};#define SIZE(_) ((_)?(_)->sz:0)struct Treap{node *root;Treap(){root=NULL;}void ins(node *&p,int a,int k){if (!p){p=node::getnew();p->k=p->mn=k;p->sz=1;}else{p->down();if (SIZE(p->l)>=a){ins(p->l,a,k);node *q=p->l;if (q->w<p->w){q->down();p->l=q->r;q->r=p;p=q;p->r->update();}}else{ins(p->r,a-SIZE(p->l)-1,k);node *q=p->r;if (q->w<p->w){q->down();p->r=q->l;q->l=p;p=q;p->l->update();}}p->update();}}void ins(int a,int k){ins(root,a,k);}static void merge(node *&p,node *x,node *y){if (!x || !y){p=x?x:y;}else if (x->w<y->w){x->down();merge(x->r,x->r,y);x->update();p=x;}else{y->down();merge(y->l,x,y->l);y->update();p=y;}}void del(node *&p,int a){p->down();if (SIZE(p->l)==a){node *q=p;merge(p,p->l,p->r);node::getnew(q);}else if (SIZE(p->l)>a){del(p->l,a);p->update();}else{del(p->r,a-SIZE(p->l)-1);p->update();}}void del(int a){del(root,a);}static void cut(node *p,node *&x,node *&y,int a){if (a==0){x=NULL;y=p;}else if (a==SIZE(p)){x=p;y=NULL;}else{p->down();if (SIZE(p->l)>=a){y=p;cut(p->l,x,y->l,a);y->update();}else{x=p;cut(p->r,x->r,y,a-SIZE(p->l)-1);x->update();}}}int ask(node *p,int a,int b){if (a==0 && b==SIZE(p)-1)return p->mn;p->down();int u=SIZE(p->l);int r=(a<=u && u<=b?p->k:~0u>>1);if (a<u)r=min(r,ask(p->l,a,b>=u?u-1:b));if (b>u)r=min(r,ask(p->r,a<=u?0:a-u-1,b-u-1));return r;}int ask(int a,int b){return ask(root,a,b);}void dfs(node *p,int lv){if (p){dfs(p->l,lv+1);for (int i=0;i<lv;i++)putchar(' '),putchar(' ');printf("%d %d %d %d %d\n",p->k,p->sz,p->mn,p->delta,p->mark);dfs(p->r,lv+1);}}void dfs(){dfs(root,0);puts("");}}T;void Ins(int a,int k){//printf("ins %d %d\n",a,k);T.ins(a,k);}void Del(int a){//printf("del %d\n",a);T.del(a);}void Revolve(int a,int b,int c){//printf("revolve %d %d %d\n",a,b,c);node *p,*q,*r,*s;Treap::cut(T.root,p,q,a);Treap::cut(q,q,r,b-a+1);Treap::cut(r,r,s,c-b);Treap::merge(p,p,r);Treap::merge(p,p,q);Treap::merge(T.root,p,s);}void Reverse(int a,int b){//printf("reverse %d %d\n",a,b);node *p,*q,*r;Treap::cut(T.root,p,q,a);Treap::cut(q,q,r,b-a+1);q->mark^=1;swap(q->l,q->r);Treap::merge(p,p,q);Treap::merge(T.root,p,r);}void Add(int a,int b,int c){//printf("add %d %d %d\n",a,b,c);node *p,*q,*r;Treap::cut(T.root,p,q,a);Treap::cut(q,q,r,b-a+1);//T.dfs(q,0);puts("");q->k+=c;q->mn+=c;q->delta+=c;//printf("c=%d\n",c);//T.dfs(q,0);//puts("");Treap::merge(p,p,q);Treap::merge(T.root,p,r);}int Ask(int a,int b){//printf("ask %d %d\n",a,b);return T.ask(a,b);}int main(){int N;scanf("%d",&N);for (int i=0;i<N;i++){int x;scanf("%d",&x);Ins(i,x);}int M;//T.dfs();scanf("%d",&M);char buf[100];while (M--){scanf("%s",buf);if (buf[0]=='A'){int x,y,d;scanf("%d%d%d",&x,&y,&d);x--;y--;Add(x,y,d);//T.dfs();}else if (buf[0]=='I'){int x,y;scanf("%d%d",&x,&y);Ins(x,y);}else if (buf[0]=='D'){int x;scanf("%d",&x);x--;Del(x);}else if (buf[0]=='M'){int x,y;scanf("%d%d",&x,&y);x--;y--;printf("%d\n",Ask(x,y));}else if (buf[3]=='E'){int x,y;scanf("%d%d",&x,&y);x--;y--;Reverse(x,y);}else{int x,y,t;scanf("%d%d%d",&x,&y,&t);x--;y--;t%=(y-x+1);t+=(y-x+1);t%=(y-x+1);if (t){Revolve(x,y-t,y);}}}return 0;}文本编辑器#include <cstdio>#include <bits/stl_pair.h>#include <queue>#include <deque>#include <algorithm>using namespace std;int ran(){static int x=222313214;x+=(x<<2)+1;return x;}struct node{int w,sz;char k;node *l,*r;static node* getnew(node *p=NULL){static node * list=NULL;if (p){p->w=ran();p->r=list;list=p;return NULL;}if (!list){node *p=new node[10000];for (int i=0;i<10000;i++){p[i].r=list;list=p+i;p[i].w=ran();}}node *q=list;list=list->r;q->l=NULL;q->r=NULL;q->sz=1;return q;}};#define SIZE(_) ((_)?(_)->sz:0)int M,curid;queue<pair<int,node*> > Literbox;deque<node*> Roots;void giveback(node *p){Literbox.push(make_pair(curid,p));}void dfs(node *p,int a,int b){if (p){int u=SIZE(p->l);if (u>a)dfs(p->l,a,min(b,u-1));if (a<=u && u<=b)putchar(p->k);if (b>u)dfs(p->r,max(a-u-1,0),b-u-1);}}node * combine(node *p,node *q){if (!p || !q)return p?p:q;if (p->w<q->w){node *a=node::getnew();a->k=p->k;a->w=p->w;a->sz=p->sz+q->sz;a->l=p->l;a->r=combine(p->r,q);giveback(p);return a;}else{node *a=node::getnew();a->k=q->k;a->w=q->w;a->sz=p->sz+q->sz;a->r=q->r;a->l=combine(p,q->l);giveback(q);return a;}}void cutdown(node *p,node *&x,node *&y,int a){if (a==0)x=NULL,y=p;else if (a==SIZE(p)){x=p;y=NULL;}else{if (SIZE(p->l)+1<=a){x=node::getnew();x->k=p->k;x->w=p->w;x->sz=a;x->l=p->l;cutdown(p->r,x->r,y,a-SIZE(p->l)-1);giveback(p);}else{y=node::getnew();y->k=p->k;y->w=p->w;y->sz=p->sz-a;y->r=p->r;cutdown(p->l,x,y->l,a);giveback(p);}}}void treeadd(node *&p,node *q){if (!p){p=q;}else{if (p->w<q->w){treeadd(p->r,q);p->sz++;}else{q->l=p;q->sz=p->sz+1;p=q;}}}void Insert(int i,char a){node *p=node::getnew();p->k=a;node *x,*y;cutdown(Roots.back(),x,y,i);x=combine(x,p);x=combine(x,y);Roots.push_back(x);curid++;}void Delete(int i){node *x,*y,*z;cutdown(Roots.back(),x,y,i);cutdown(y,y,z,1);giveback(y);x=combine(x,z);Roots.push_back(x);curid++;}void Revolve(int a,int b,int c){node *p,*q,*r,*s;cutdown(Roots.back(),p,q,a);cutdown(q,q,r,b-a+1);cutdown(r,r,s,c-b);p=combine(p,r);p=combine(p,q);p=combine(p,s);Roots.push_back(p);curid++;}void Print(int a,int x,int y){node *p=Roots.at(Roots.size()-1-a);dfs(p,x,y);puts("");}void readstr(vector<char> &a){char c;while (c=getchar(),c==10 || c==13 || c==' ');while (c!=10 && c!=13){a.push_back(c);c=getchar();}}int main(){scanf("%d",&M);vector<char> chs;readstr(chs);node *r=NULL;for (int i=0;i<(int)chs.size();i++){node *p=node::getnew();p->k=chs[i];treeadd(r,p);}Roots.push_back(r);curid=0;char cmd[10];while (scanf("%s",cmd)!=EOF){if (cmd[0]=='I'){int x;scanf("%d",&x);scanf("%s",cmd);Insert(x,cmd[0]);}else if (cmd[0]=='D'){int x;scanf("%d",&x);Delete(x-1);}else if (cmd[0]=='P'){int x,y,z;scanf("%d%d%d",&x,&y,&z);Print(x,y-1,z-1);}else if (cmd[0]=='C'){int x,y,z;scanf("%d%d%d",&x,&y,&z);Revolve(x-1,y-1,z-1);}while (!Literbox.empty() && Literbox.front().first<curid-M){node::getnew(Literbox.front().second);Literbox.pop();}while ((int)Roots.size()>M)Roots.pop_front();}return 0;}