博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[AH2017/HNOI2017]单旋
阅读量:5146 次
发布时间:2019-06-13

本文共 2740 字,大约阅读时间需要 9 分钟。

\(\rm splay\)水平太差,于是得手玩一下才能发现规律

首先插入一个数,其肯定会成为其前驱的右儿子或者是后继的左儿子,进一步手玩发现前驱的右儿子或者是后继的左儿子一定只有一个是空的,我们找到这个空位置插入就好了

于是我们需要一个\(\rm std::set\)来查找前驱后继,同时我们还需要维护每个点的左右儿子和父亲

继续手玩发现由于只有对最大值和最小值的操作,所以对\(\rm splay\)的结构影响很小,于是这个过程中也能维护每个节点的父亲的左右儿子

深度看起来不能用几个数组来维护了,于是我们直接用lct维护这棵树的形态,深度查一下到当前根的路径上的节点个数即可

代码

#include
#define re registerinline int read() { char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;}const int maxn=1e5+5;struct LinkCutTree { int fa[maxn],ch[maxn][2],sz[maxn],rev[maxn]; int st[maxn],top; inline int nrt(int x) {return ch[fa[x]][1]==x||ch[fa[x]][0]==x;} inline void pushup(int x) {sz[x]=sz[ch[x][0]]+1+sz[ch[x][1]];} inline void rotate(int x) { int y=fa[x],z=fa[y],w=ch[y][1]==x,k=ch[x][w^1]; if(nrt(y)) ch[z][ch[z][1]==y]=x; ch[x][w^1]=y,ch[y][w]=k; pushup(y),pushup(x);fa[k]=y,fa[y]=x,fa[x]=z; } inline void work(int x) {rev[x]^=1;std::swap(ch[x][0],ch[x][1]);} inline void pushdown(int x) { if(!rev[x]) return;rev[x]=0; if(ch[x][0]) work(ch[x][0]); if(ch[x][1]) work(ch[x][1]); } inline void splay(int x) { int y=x;top=0; st[++top]=x; while(nrt(y)) y=fa[y],st[++top]=y; while(top) pushdown(st[top--]); while(nrt(x)) { int y=fa[x]; if(nrt(y)) rotate((ch[y][1]==x)^(ch[fa[y]][1]==y)?x:y); rotate(x); } } inline void access(int x) { for(re int y=0;x;y=x,x=fa[x]) splay(x),ch[x][1]=y,pushup(x); } inline void mrt(int x) { access(x);splay(x);work(x); } inline void link(int x,int y) { mrt(x);fa[x]=y; } inline void split(int x,int y) { mrt(x),access(y),splay(y); } inline void cut(int x,int y) { split(x,y);fa[x]=ch[y][0]=0;pushup(y); } inline int dis(int x,int y) { split(x,y);return sz[y]; }}lct;struct RBT { std::set
s; #define It std::set
::iterator inline int pre(int x) { It it=s.find(x); if(it==s.begin()) return 0; --it;return *it; } inline int nxt(int x) { It it=s.find(x);++it; if(it==s.end()) return 0; return *it; } inline void del(int x) {s.erase(x);} inline void ins(int x) {s.insert(x);} inline int Gmin() {It it=s.begin();return *it;} inline int Gmax() {It it=s.end();--it;return *it;} inline int empty() {return s.empty();}}s;int n,m,rt;int a[maxn],b[maxn],son[maxn][2],op[maxn],fa[maxn];inline int find(int x) { int l=1,r=n; while(l<=r) { int mid=l+r>>1; if(b[mid]==x) return mid; if(b[mid]

转载于:https://www.cnblogs.com/asuldb/p/11492087.html

你可能感兴趣的文章
Python数据可视化之Pygal(雷达图)
查看>>
Java学习笔记--字符串和文件IO
查看>>
转 Silverlight开发历程—(画刷与着色之线性渐变画刷)
查看>>
SQL语法(3)
查看>>
在js在添版本号
查看>>
sublime3
查看>>
Exception Type: IntegrityError 数据完整性错误
查看>>
Nuget:Newtonsoft.Json
查看>>
Hdu - 1002 - A + B Problem II
查看>>
每天CookBook之Python-003
查看>>
每天CookBook之Python-004
查看>>
Android设置Gmail邮箱
查看>>
js编写时间选择框
查看>>
Java数据结构和算法(四)--链表
查看>>
JIRA
查看>>
小技巧——直接在目录中输入cmd然后就打开cmd命令窗口
查看>>
深浅拷贝(十四)
查看>>
HDU 6370(并查集)
查看>>
BZOJ 1207(dp)
查看>>
PE知识复习之PE的导入表
查看>>