当前位置: 首页 > news >正文

网站内容更新外包最新足球新闻头条

网站内容更新外包,最新足球新闻头条,极客优选网上商城系统,新闻最新北京消息今天前言 Splay是一种维护平衡二叉树的算法。虽然它常数大,而且比较难打,但Splay十分方便,而且LCT需要用到。 约定 cnticnt_icnti​:节点iii的个数 valival_ivali​:节点iii的权值 sizisiz_isizi​:节点iii的子…

前言

Splay是一种维护平衡二叉树的算法。虽然它常数大,而且比较难打,但Splay十分方便,而且LCT需要用到。


约定

cnticnt_icnti:节点iii的个数
valival_ivali:节点iii的权值
sizisiz_isizi:节点iii的子树大小
chi,0/1ch_{i,0/1}chi,0/1:节点iii的左右儿子
faifa_ifai节点iii的父亲
rootrootroot当前的根节点
tottottot当前的节点数量

gt(x)gt(x)gt(x):返回xxx是左儿子还是右儿子
pushup(x)pushup(x)pushup(x):更新当前子树大小

int gt(int x){return ch[fa[x]][1]==x;
}
void pt(int x){siz[x]=cnt[x]+siz[ch[x][0]]+siz[ch[x][1]];
}

基本操作

旋转操作

在这里插入图片描述

  • yyyzzz的哪个儿子,xxx就是zzz的哪个儿子
  • xxxyyy的哪个儿子,yyy就是xxx的对应儿子的兄弟
  • xxxyyy的哪个儿子,yyy的那个儿子就是xxx的对应儿子的兄弟
void rot(int x){int y=fa[x],z=fa[y],k=gt(x);ch[z][gt(y)]=x,fa[x]=z;ch[y][k]=ch[x][!k],fa[ch[y][k]]=y;ch[x][!k]=y,fa[y]=x;pt(y);pt(x);
}

伸展操作

splay(x,g)splay(x,g)splay(x,g),表示将xxx旋转到ggg下面。

我们可以一直rotrotrot,但如果xxx的父亲不是gggxxxxxx的父亲是同一边的儿子,则可以旋转父亲。先旋转父亲可以减少深度。

void splay(int x,int g=0){for(int y;fa[x]!=g;rot(x)){y=fa[x];if(fa[y]!=g) rot((gt(x)==gt(y))?y:x);}if(!g) root=x;
}

普通操作

find操作

找到值最接近xxx的点,并伸展到根。

void find(int x){if(!root) return;int u=root;while(ch[u][x>v[u]]&&x^v[u]) u=ch[u][x>v[u]];splay(u);
}

insert操作

插入值为xxx的点,需进行一下操作

  • 找到插入点的位置
  • 如果存在值为xxx的点,则加对应的cntcntcnt
  • 否则新加一个点
  • 把该节点伸展到根
void insert(int x){int u=root,fu=0;while(u&&v[u]!=x){fu=u,u=ch[u][x>v[u]];}if(u) ++cnt[u];else{u=++tot;if(fu) ch[fu][x>v[fu]]=u;fa[u]=fu;v[u]=x;cnt[u]=siz[u]=1;}splay(u);
}

前驱和后继

xxx的前驱和后继

find(x)find(x)find(x),那么前驱就是左子树中最大的一个,后继就是右子树中最小的一个。

int nxt(int x,int f){find(x);int u=root;if(v[u]>x&&f) return u;if(v[u]<x&&!f) return u;u=ch[u][f];while(ch[u][!f]) u=ch[u][!f];return u;
}

delete操作

删除值为xxx的点

首先找到xxx的前驱sucsucsucxxx的后继preprepre,然后

  • splay(pre)splay(pre)splay(pre)
  • splay(suc,pre)splay(suc,pre)splay(suc,pre)

然后sucsucsuc的左子树就是要删除的点,删除即可。

void dele(int x){int lt=nxt(x,0),nt=nxt(x,1);splay(lt);splay(nt,lt);int tx=ch[nt][0];if(cnt[tx]>1) --cnt[tx],splay(tx);else ch[nt][0]=0;
}

kth操作

找到排名为kkk的节点的权值

int kth(int k){int u=root,sn=0;for(;;){sn=ch[u][0];if(k>siz[sn]+cnt[u]) k-=siz[sn]+cnt[u],u=ch[u][1];else if(siz[sn]>=k) u=sn;else return v[u];}
}

例题

普通平衡树

对于操作1,2,4,5,6,可以用上述操作解决即可。对于操作3,可以find(x)find(x)find(x)将其置为根,然后xxx的排名就是它左子树的节点个数+1+1+1

注意为了防止splaysplaysplay出锅,要在加上两个节点∞\infty−∞-\infty。注意这两个节点对操作的影响。

#include<iostream>
#include<cstdio>
#define N 500000
using namespace std;
int root,tot,t,cnt[N],v[N],siz[N],ch[N][2],fa[N];
int gt(int x){return ch[fa[x]][1]==x;
}//Return 0 or 1 means x is the left or right son
void pt(int x){siz[x]=cnt[x]+siz[ch[x][0]]+siz[ch[x][1]];
}//Update the x
void rot(int x){int y=fa[x],z=fa[y],k=gt(x);ch[z][gt(y)]=x,fa[x]=z;ch[y][k]=ch[x][!k],fa[ch[y][k]]=y;ch[x][!k]=y,fa[y]=x;pt(y);pt(x);
}//Rotate
void splay(int x,int g=0){for(int y;fa[x]!=g;rot(x)){y=fa[x];if(fa[y]!=g) rot((gt(x)==gt(y))?y:x);}if(!g) root=x;
}//Put the x under the g
void find(int x){if(!root) return;int u=root;while(ch[u][x>v[u]]&&x^v[u]) u=ch[u][x>v[u]];splay(u);
}//Find the closest node and put it under the root
void insert(int x){int u=root,fu=0;while(u&&v[u]!=x){fu=u,u=ch[u][x>v[u]];}if(u) ++cnt[u];else{u=++tot;if(fu) ch[fu][x>v[fu]]=u;fa[u]=fu;v[u]=x;cnt[u]=siz[u]=1;}splay(u);
}//Insert the x
//1.Find the root which should be inserted
//2.If there is a node as same as it,plus its cnt
//3.Else plus a node
//4.Make the new node be the root
int nxt(int x,int f){find(x);int u=root;if(v[u]>x&&f) return u;if(v[u]<x&&!f) return u;u=ch[u][f];while(ch[u][!f]) u=ch[u][!f];return u;
}//Find the suc or the pre of the x
//After finding x,then
//The pre is the biggest one in left tree
//The suc is the smallest one in right tree
void dele(int x){int lt=nxt(x,0),nt=nxt(x,1);splay(lt);splay(nt,lt);int tx=ch[nt][0];if(cnt[tx]>1) --cnt[tx],splay(tx);else ch[nt][0]=0;
}//Find the pre and the suc of the x
//Splay(pre),splay(suc,pre)
//Then delete the left son of the suc
int kth(int k){int u=root,sn=0;for(;;){sn=ch[u][0];if(k>siz[sn]+cnt[u]) k-=siz[sn]+cnt[u],u=ch[u][1];else if(siz[sn]>=k) u=sn;else return v[u];}
}
int main()
{insert(2147483647);insert(-2147483647);scanf("%d",&t);while(t--){int op,x;scanf("%d%d",&op,&x);if(op==1) insert(x);else if(op==2) dele(x);else if(op==3) find(x),printf("%d\n",siz[ch[root][0]]);else if(op==4) printf("%d\n",kth(x+1));else if(op==5) printf("%d\n",v[nxt(x,0)]);else printf("%d\n",v[nxt(x,1)]);}return 0;
}
http://www.hkea.cn/news/146891/

相关文章:

  • 顺义专业建站公司最有效的线上推广方式
  • 大连网站网站搭建制作百度识图 上传图片
  • 给人做网站多少钱黑科技引流推广神器怎么下载
  • 沈阳做网站最好的公司百度快照怎么删除
  • 设置本机外网ip做网站网站免费制作平台
  • 有什么推荐做简历的网站2024的新闻有哪些
  • 申请做网站 论坛版主惠州seo外包服务
  • 网站照片上传不了域名解析ip
  • 胖小七网站建设2022最新国际新闻10条简短
  • wordpress 网站备份厦门seo外包服务
  • 网站建设及推广培训杭州百度快照优化排名
  • 简单手机网站开发软件关键词排名代发
  • visio画网站开发类图注册域名后怎么建网站
  • 道里网站运营培训北京网络营销咨询公司
  • 目前做网站流行的语言seo关键词排名优化哪家好
  • 长沙营销型网站制作费用seo图片优化
  • 学生诚信档案建设网站seo数据分析
  • 北京住房城乡建设厅网站首页1688官网入口
  • 网站建设需要懂什么软件徐州百度seo排名优化
  • wordpress网站样式网站排名查询
  • 郑州网站建设推销外贸网站推广与优化
  • 当当网站开发系统说明搜索引擎排名google
  • 国外男女直接做的视频网站企业邮箱登录入口
  • 成都可以做网站的公司百度手机助手最新版下载
  • 赤峰网站建设招聘市场营销互联网营销
  • 网站开发后端需要哪些技术友情链接检索数据分析
  • 金华竞价排名 金华企业网站建设常见的网络营销平台有哪些
  • p2p网站开发关键词seo是什么意思
  • 自己免费怎么制作网站合肥今天的最新消息
  • 今日头条新闻10条简短seo网络优化招聘信息