fhq treap

最近突然想学平衡树,原先想学splay,但是splay太难了,代码又长,本蒟蒻不大理解,又听机房的大佬们说有一种神奇的平衡树--fhq发明的fhq treap,能完成splay的所有功能又容易理解,代码短,便兴致勃勃地去学了。

最好先去学treap或了解一下treap,知道一些常识

先推荐两篇blog:

http://www.yhzq-blog.cc/fhq-treap%E6%80%BB%E7%BB%93/

https://www.cnblogs.com/Sakits/p/7906318.html

这篇文章也是参考这两篇blog写的,某些图片、代码、文字也转自这篇blog

 

在阅读我的文章时,如果中间有不确定的部分,可以先跳到后面的完整代码研究。

fhq treap又称无旋treap,是通过分裂和合并来完成各种插入区间,删除区间,翻转区间等操作的。

 我们来讲讲它的两个关键操作:分裂和合并

分裂:把一棵子树分成l,r两棵子树。

把前k个分到左子树,其他分到右子树

 

inline void sl(ll x,ll &l,ll &r,ll k){
    if(!k)r=x,l=0;
    else if(k==tr[x].siz)l=x,r=0;
    else (k<=tr[lt].siz)?(pd(r=x),sl(lt,l,lt,k)):(pd(l=x),sl(rt,rt,r,k-tr[lt].siz-1)),pu(x);
}
//lt指左子树,rt指右子树,siz指子树大小,pd指下推,pu指向上更新
View Code

 

合并:把l子树和r子树合并为子树x

如图:

转自http://www.yhzq-blog.cc

转自http://www.yhzq-blog.cc

1 inline void mg(ll &x,ll l,ll r){
2     if(!l||!r)x=l+r;
3     else (tr[l].rnd<tr[r].rnd)?(pd(x=l),mg(rt,rt,r)):(pd(x=r),mg(lt,l,lt)),pu(x);
4 }
5 //rnd指一棵子树的随机权值(学过treap的肯定知道)
View Code

 

新建一个节点:

1 inline void bt(ll &x,ll v){
2     tr[x=++sz].rnd=rand()<<15|rand();
3     tr[x].s=v;tr[x].siz=1;
4 }
5 //s指节点的值,siz指这个节点和它的子树一共有多少节点
View Code

 

接下来是insert:插入一个值为v的节点

先找v的排名,然后分裂,排在v前面的分在左子树,其他的在右子树,然后在中间插入这个节点,接着把三个部分合并在一起。

1 inline void ins(ll v){
2     ll x,y,rk=rank(RT,v),nt;
3     sl(RT,x,y,rk);bt(nt,v);
4     mg(x,x,nt);mg(RT,x,y);
5 }
View Code

 

完整代码:(bzoj 3224: Tyvj 1728 普通平衡树)

 1 #include<bits/stdc++.h>
 2 #define ll int
 3 #define max(x,y) ((x)>(y)?(x):(y))
 4 #define min(x,y) ((x)<(y)?(x):(y))
 5 #define fur(i,x,y) for(i=x;i<=y;i++)
 6 #define fdr(i,x,y) for(i=x;i>=y;i--)
 7 #define Fur(i,x,y) for(ll i=x;i<=y;i++)
 8 #define Fdr(i,x,y) for(ll i=x;i>=y;i--)
 9 #define in2(x,y) in(x);in(y)
10 #define in3(x,y,z) in2(x,y);in(z)
11 #define in4(a,b,c,d) in2(a,b);in2(c,d)
12 #define clr(x,y) memset(x,y,sizeof(x))
13 #define cpy(x,y) memcpy(x,y,sizeof(x))
14 #define fl(i,x) for(ll i=head[x],to;to=e[i].to,i;i=e[i].next)
15 #define inf 233333333
16 using namespace std;
17 /*---------------------------------------*/
18 #define pob (fwrite(fob::b,sizeof(char),fob::f-fob::b,stdout),fob::f=fob::b,0)
19 #define pc(x) (*(fob::f++)=(x),(fob::f==fob::g)?pob:0)
20 #define gc ((*fib::f)?(*(fib ::f++)):(fgets(fib::b,sizeof(fib::b),stdin)?(fib::f=fib::b,*(fib::f++)):-1))
21 namespace fib{char b[300000]= {},*f=b;}inline void in(ll &x){x=0;char c;bool f=0;while((c=gc)>'9'||c<'0')if(c=='-')f=!f;x=c-48;while((c=gc)<='9'&&c>='0')x=x*10+c-48;if(f)x=-x;}namespace fob{char b[300000]= {},*f=b,*g=b+300000-2;}struct foce{~foce(){pob;fflush(stdout);}} _foce;namespace ib{char b[100];}inline void out(ll x){if(x==0){pc(48);return;}if(x<0){pc('-');x=-x;}char *s=ib::b;while(x) *(++s)=x%10,x/=10;while(s!=ib::b) pc((*(s--))+48);}inline void outn(ll x){out(x);pc('\n');}
22 inline void swap(ll &x,ll &y){ll t=x;x=y;y=t;}
23 inline ll jdz(ll x){return x>=0?x:-x;}
24 /*------------------------------------------------------------------------------------------------*/
25 #define N 110000
26 #define lt tr[x].ls
27 #define rt tr[x].rs
28 ll n,sz=0,RT;
29 struct fhq{ll siz,s,rnd,ls,rs;}tr[N];
30 inline void pu(ll x){tr[x].siz=tr[lt].siz+tr[rt].siz+1;}
31 inline void bt(ll &x,ll v){
32     tr[x=++sz].rnd=rand()<<15|rand();
33     tr[x].s=v;tr[x].siz=1;
34 }
35 inline void sl(ll x,ll &l,ll &r,ll k){
36     if(!k)r=x,l=0;
37     else if(k==tr[x].siz)l=x,r=0;
38     else (k<=tr[lt].siz)?(r=x,sl(lt,l,lt,k)):(l=x,sl(rt,rt,r,k-tr[lt].siz-1)),pu(x);
39 }
40 inline void mg(ll &x,ll l,ll r){
41     if(!l||!r)x=l+r;
42     else (tr[l].rnd<tr[r].rnd)?(x=l,mg(rt,rt,r)):(x=r,mg(lt,l,lt)),pu(x);
43 }
44 inline ll rank(ll x,ll v){
45     if(!x)return 0;
46     return (tr[x].s>=v)?rank(lt,v):rank(rt,v)+tr[lt].siz+1;
47 }
48 inline void ins(ll v){
49     ll x,y,rk=rank(RT,v),nt;
50     sl(RT,x,y,rk);bt(nt,v);
51     mg(x,x,nt);mg(RT,x,y);
52 }
53 inline void del(ll v){
54     ll x,y,z,rk=rank(RT,v)+1;
55     sl(RT,x,y,rk);sl(x,x,z,rk-1);
56     mg(RT,x,y);
57 }
58 inline ll find(ll k){
59     ll x,y,z,ans;
60     sl(RT,x,y,k);sl(x,z,x,k-1);
61     ans=tr[x].s;
62     mg(x,z,x);mg(RT,x,y);
63     return ans;
64 }
65 inline ll pre(ll v){
66     ll x,y,z,ans,rk=rank(RT,v);
67     sl(RT,x,y,rk);sl(x,z,x,rk-1);
68     ans=tr[x].s;
69     mg(x,z,x);mg(RT,x,y);
70     return ans;
71 }
72 inline ll nxt(ll v){
73     ll x,y,z,ans,rk=rank(RT,v+1);
74     sl(RT,x,y,rk+1);sl(x,z,x,rk);
75     ans=tr[x].s;
76     mg(x,z,x);mg(RT,x,y);
77     return ans;
78 }
79 int main(){
80     ll u,x;
81     srand(19260817);
82     in(n);tr[0].rnd=tr[0].s=inf;
83     while(n--){
84         in2(u,x);
85         switch(u){
86             case 1:ins(x);break;
87             case 2:del(x);break;
88             case 3:outn(rank(RT,x)+1);break;
89             case 4:outn(find(x));break;
90             case 5:outn(pre(x));break;
91             case 6:outn(nxt(x));break;
92         }
93     }
94 }
View Code

 

bzoj 3223: Tyvj 1729 文艺平衡树:

加上了翻转标记

 1 #include<bits/stdc++.h>
 2 #define ll int
 3 #define max(x,y) ((x)>(y)?(x):(y))
 4 #define min(x,y) ((x)<(y)?(x):(y))
 5 #define fur(i,x,y) for(i=x;i<=y;i++)
 6 #define fdr(i,x,y) for(i=x;i>=y;i--)
 7 #define Fur(i,x,y) for(ll i=x;i<=y;i++)
 8 #define Fdr(i,x,y) for(ll i=x;i>=y;i--)
 9 #define in2(x,y) in(x);in(y)
10 #define in3(x,y,z) in2(x,y);in(z)
11 #define in4(a,b,c,d) in2(a,b);in2(c,d)
12 #define clr(x,y) memset(x,y,sizeof(x))
13 #define cpy(x,y) memcpy(x,y,sizeof(x))
14 #define fl(i,x) for(ll i=head[x],to;to=e[i].to,i;i=e[i].next)
15 #define inf 233333333
16 using namespace std;
17 /*---------------------------------------*/
18 #define pob (fwrite(fob::b,sizeof(char),fob::f-fob::b,stdout),fob::f=fob::b,0)
19 #define pc(x) (*(fob::f++)=(x),(fob::f==fob::g)?pob:0)
20 #define gc ((*fib::f)?(*(fib ::f++)):(fgets(fib::b,sizeof(fib::b),stdin)?(fib::f=fib::b,*(fib::f++)):-1))
21 namespace fib{char b[300000]= {},*f=b;}inline void in(ll &x){x=0;char c;bool f=0;while((c=gc)>'9'||c<'0')if(c=='-')f=!f;x=c-48;while((c=gc)<='9'&&c>='0')x=x*10+c-48;if(f)x=-x;}namespace fob{char b[300000]= {},*f=b,*g=b+300000-2;}struct foce{~foce(){pob;fflush(stdout);}} _foce;namespace ib{char b[100];}inline void out(ll x){if(x==0){pc(48);return;}if(x<0){pc('-');x=-x;}char *s=ib::b;while(x) *(++s)=x%10,x/=10;while(s!=ib::b) pc((*(s--))+48);}inline void outn(ll x){out(x);pc('\n');}
22 inline void swap(ll &x,ll &y){ll t=x;x=y;y=t;}
23 inline ll jdz(ll x){return x>=0?x:-x;}
24 /*------------------------------------------------------------------------------------------------*/
25 #define N 51000
26 #define lt tr[x].ls
27 #define rt tr[x].rs
28 ll n,q,sz=0,RT;
29 struct fhq{ll siz,s,mx,rnd,ls,rs,rev,add;}tr[N];
30 inline void build(ll &x,ll v){
31     tr[x=++sz].rnd=rand()<<15|rand();
32     tr[x].s=tr[x].mx=v;tr[x].siz=1;
33 }
34 inline void fz(ll x){tr[x].rev^=1;swap(lt,rt);}
35 inline void upd(ll x,ll v){if(x)tr[x].add+=v,tr[x].s+=v,tr[x].mx+=v;}
36 inline void pd(ll x){
37     if(!x)return;
38     if(tr[x].rev){fz(lt);fz(rt);}tr[x].rev=0;
39     ll &t=tr[x].add;
40     if(t){upd(lt,t);upd(rt,t);t=0;}
41 }
42 inline void pu(ll x){
43     if(!x)return;
44     tr[x].siz=tr[lt].siz+tr[rt].siz+1;
45     tr[x].mx=max(tr[x].s,max(tr[lt].mx,tr[rt].mx));
46 }
47 inline void sl(ll x,ll &l,ll &r,ll k){
48     if(!k)r=x,l=0;
49     else if(k==tr[x].siz)l=x,r=0;
50     else (k<=tr[lt].siz)?(pd(r=x),sl(lt,l,lt,k)):(pd(l=x),sl(rt,rt,r,k-tr[lt].siz-1)),pu(x);
51 }
52 inline void mg(ll &x,ll l,ll r){
53     if(!l||!r)x=l+r;
54     else (tr[l].rnd<tr[r].rnd)?(pd(x=l),mg(rt,rt,r)):(pd(x=r),mg(lt,l,lt)),pu(x);
55 }
56 inline void work(){
57     ll x,y,z,l,r,u,v;
58     in3(u,l,r);
59     sl(RT,x,y,r);sl(x,z,x,l-1);
60     if(u==1){in(v);upd(x,v);}
61     if(u==2)fz(x);
62     if(u==3)outn(tr[x].mx);
63     mg(x,z,x);mg(RT,x,y);
64 }
65 int main(){
66     srand(19260807);tr[0].rnd=inf;tr[0].s=tr[0].mx=-inf;
67     ll x;
68     in2(n,q);
69     Fur(i,1,n){build(x,0);mg(RT,RT,x);}
70     while(q--)work();
71 }
View Code

 

bzoj 1251: 序列终结者

加上翻转、add标记

 1 #include<bits/stdc++.h>
 2 #define ll int
 3 #define max(x,y) ((x)>(y)?(x):(y))
 4 #define min(x,y) ((x)<(y)?(x):(y))
 5 #define fur(i,x,y) for(i=x;i<=y;i++)
 6 #define fdr(i,x,y) for(i=x;i>=y;i--)
 7 #define Fur(i,x,y) for(ll i=x;i<=y;i++)
 8 #define Fdr(i,x,y) for(ll i=x;i>=y;i--)
 9 #define in2(x,y) in(x);in(y)
10 #define in3(x,y,z) in2(x,y);in(z)
11 #define in4(a,b,c,d) in2(a,b);in2(c,d)
12 #define clr(x,y) memset(x,y,sizeof(x))
13 #define cpy(x,y) memcpy(x,y,sizeof(x))
14 #define fl(i,x) for(ll i=head[x],to;to=e[i].to,i;i=e[i].next)
15 #define inf 233333333
16 using namespace std;
17 /*---------------------------------------*/
18 #define pob (fwrite(fob::b,sizeof(char),fob::f-fob::b,stdout),fob::f=fob::b,0)
19 #define pc(x) (*(fob::f++)=(x),(fob::f==fob::g)?pob:0)
20 #define gc ((*fib::f)?(*(fib ::f++)):(fgets(fib::b,sizeof(fib::b),stdin)?(fib::f=fib::b,*(fib::f++)):-1))
21 namespace fib{char b[300000]= {},*f=b;}inline void in(ll &x){x=0;char c;bool f=0;while((c=gc)>'9'||c<'0')if(c=='-')f=!f;x=c-48;while((c=gc)<='9'&&c>='0')x=x*10+c-48;if(f)x=-x;}namespace fob{char b[300000]= {},*f=b,*g=b+300000-2;}struct foce{~foce(){pob;fflush(stdout);}} _foce;namespace ib{char b[100];}inline void out(ll x){if(x==0){pc(48);return;}if(x<0){pc('-');x=-x;}char *s=ib::b;while(x) *(++s)=x%10,x/=10;while(s!=ib::b) pc((*(s--))+48);}inline void outn(ll x){out(x);pc('\n');}
22 inline void swap(ll &x,ll &y){ll t=x;x=y;y=t;}
23 inline ll jdz(ll x){return x>=0?x:-x;}
24 /*------------------------------------------------------------------------------------------------*/
25 #define N 51000
26 #define lt tr[x].ls
27 #define rt tr[x].rs
28 ll n,q,sz=0,RT;
29 struct fhq{ll siz,s,mx,rnd,ls,rs,rev,add;}tr[N];
30 inline void build(ll &x,ll v){
31     tr[x=++sz].rnd=rand()<<15|rand();
32     tr[x].s=tr[x].mx=v;tr[x].siz=1;
33 }
34 inline void fz(ll x){tr[x].rev^=1;swap(lt,rt);}
35 inline void upd(ll x,ll v){if(x)tr[x].add+=v,tr[x].s+=v,tr[x].mx+=v;}
36 inline void pd(ll x){
37     if(!x)return;
38     if(tr[x].rev){fz(lt);fz(rt);}tr[x].rev=0;
39     ll &t=tr[x].add;
40     if(t){upd(lt,t);upd(rt,t);t=0;}
41 }
42 inline void pu(ll x){
43     if(!x)return;
44     tr[x].siz=tr[lt].siz+tr[rt].siz+1;
45     tr[x].mx=max(tr[x].s,max(tr[lt].mx,tr[rt].mx));
46 }
47 inline void sl(ll x,ll &l,ll &r,ll k){
48     if(!k)r=x,l=0;
49     else if(k==tr[x].siz)l=x,r=0;
50     else (k<=tr[lt].siz)?(pd(r=x),sl(lt,l,lt,k)):(pd(l=x),sl(rt,rt,r,k-tr[lt].siz-1)),pu(x);
51 }
52 inline void mg(ll &x,ll l,ll r){
53     if(!l||!r)x=l+r;
54     else (tr[l].rnd<tr[r].rnd)?(pd(x=l),mg(rt,rt,r)):(pd(x=r),mg(lt,l,lt)),pu(x);
55 }
56 inline void work(){
57     ll x,y,z,l,r,u,v;
58     in3(u,l,r);
59     sl(RT,x,y,r);sl(x,z,x,l-1);
60     if(u==1){in(v);upd(x,v);}
61     if(u==2)fz(x);
62     if(u==3)outn(tr[x].mx);
63     mg(x,z,x);mg(RT,x,y);
64 }
65 int main(){
66     srand(19260807);tr[0].rnd=inf;tr[0].s=tr[0].mx=-inf;
67     ll x;
68     in2(n,q);
69     Fur(i,1,n){build(x,0);mg(RT,RT,x);}
70     while(q--)work();
71 }
View Code

 

转载于:https://www.cnblogs.com/mimiorz/p/9158446.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值