合肥网站建设优化学习5151app是交友软件么
web/
2025/10/7 5:30:14/
文章来源:
合肥网站建设优化学习,5151app是交友软件么,windows2008 iis 网站配置,wordpress 架构设计dist 的性质
对于一棵二叉树#xff0c;我们定义左孩子或右孩子为空的节点为外节点#xff0c;定义外节点的 distdist 为 11#xff0c;空节点的 distdist 为 00#xff0c;不是外节点也不是空节点的 distdist 为其到子树中最近的外节点的距离加一。 一棵根的 distdist 为…dist 的性质
对于一棵二叉树我们定义左孩子或右孩子为空的节点为外节点定义外节点的 distdist 为 11空节点的 distdist 为 00不是外节点也不是空节点的 distdist 为其到子树中最近的外节点的距离加一。 一棵根的 distdist 为 xx 的二叉树至少有 2x−12x−1 个节点。此性质所有二叉树都有并非左偏树特有。 distdist 不是深度左偏树的深度没有保证一条向左的链也是左偏树。
左偏树的性质
左偏树是一棵二叉树并且是“左偏”的即每个节点左儿子的 distdist 都大于等于右儿子的 distdist。 因此左偏树中每个节点的 distdist 是它右儿子的 distdist 加一。
变量
int lson[N], rson[N], fa[N], fat[N];
ll val[N], dist[N];lson: 左孩子左偏rson: 右孩子fa: 父节点fat: 祖先并查集val: 权值dist: 就是 distdist。
操作 合并
int merge(int x, int y) { // 合并if (!x || !y) {return x | y;}if (val[x] val[y] || (val[x] val[y] x y))swap(x, y);rson[x] merge(rson[x], y);fat[rson[x]] fa[rson[x]] x;if (dist[lson[x]] dist[rson[x]])swap(lson[x], rson[x]);dist[x] dist[rson[x]] 1;return x;
}if (!x || !y) { return x | y; } 如果与空节点合并则直接合并即可if (val[x] val[y] || (val[x] val[y] x y)) 说明这是个小根堆小元素在上面。if (dist[lson[x]] dist[rson[x]]) swap(lson[x], rson[x]); 维护左偏的性质。 删除任意一个节点
左偏树是不支持删除给定权值的点的只能删除知道点的标号的点。
void earse(int u) { // 删除任意一点int tmp merge(lson[u], rson[u]), fu fa[u];fat[tmp] fa[tmp] fu;fat[u] fa[u] tmp;lson[fu] u ? lson[fu] tmp : rson[fu] tmp;while (fu) {if (dist[lson[fu]] dist[rson[fu]])swap(lson[fu], rson[fu]);if (dist[fu] dist[rson[fu]] 1)return ;dist[fu] dist[rson[fu]] 1;fu fa[fu];}
}int tmp merge(lson[u], rson[u]), fu fa[u]; 先将被删节点的左右孩子合并。fat[tmp] fa[tmp] fu; 处理好父亲和孩子的关系。
while (fu) {if (dist[lson[fu]] dist[rson[fu]])swap(lson[fu], rson[fu]);if (dist[fu] dist[rson[fu]] 1)return ;dist[fu] dist[rson[fu]] 1;fu fa[fu];
}删除点之后可能不符合左偏性质需要我们向上修改直到到根节点或符合左偏性质为止。 查询 uu 点所在堆的堆顶元素的标号
这个操作类似于并查集操作。
int find(int u) { // 查询堆顶的元素的标号return (fat[u] u || fat[u] 0) ? u : fat[u] find(fat[u]);
}删除 uu 点所在堆的堆顶元素
void pop(int u) { // 弹出 u 点所在对的堆顶元素int g find(u);earse(g);
}查询 uu 点所在堆的堆顶元素
ll top(int u) { // 查询 u 点所在堆的堆顶元素int g find(u);return val[g];
}建树操作
int build(int n) { // 建树queueint q;for (int i 1; i n; i) {q.push(i);}int x, y, z;while (q.size() 1) {x q.front(), q.pop();y q.front(), q.pop();z merge(x, y), q.push(z);}return q.front();
}模板
// 左偏树小根堆
struct leftist_tree {int lson[N], rson[N], fa[N], fat[N];ll val[N], dist[N];int merge(int x, int y) { // 合并if (!x || !y) {return x | y;}if (val[x] val[y] || (val[x] val[y] x y))swap(x, y);rson[x] merge(rson[x], y);fat[rson[x]] fa[rson[x]] x;if (dist[lson[x]] dist[rson[x]])swap(lson[x], rson[x]);dist[x] dist[rson[x]] 1;return x;}int find(int u) { // 查询堆顶的元素的标号return (fat[u] u || fat[u] 0) ? u : fat[u] find(fat[u]);}void earse(int u) { // 删除任意一点int tmp merge(lson[u], rson[u]), fu fa[u];fat[tmp] fa[tmp] fu;fat[u] fa[u] tmp;lson[fu] u ? lson[fu] tmp : rson[fu] tmp;while (fu) {if (dist[lson[fu]] dist[rson[fu]])swap(lson[fu], rson[fu]);if (dist[fu] dist[rson[fu]] 1)return ;dist[fu] dist[rson[fu]] 1;fu fa[fu];}}ll top(int u) { // 查询 u 点所在堆的堆顶元素int g find(u);return val[g];}void pop(int u) { // 弹出 u 点所在对的堆顶元素int g find(u);earse(g);}int build(int n) { // 建树queueint q;for (int i 1; i n; i) {q.push(i);}int x, y, z;while (q.size() 1) {x q.front(), q.pop();y q.front(), q.pop();z merge(x, y), q.push(z);}return q.front();}
};pb_ds 中的堆
__gnu_pbds :: priority_queue
成员函数 push(): 向堆中压入一个元素返回该元素位置的迭代器。pop(): 将堆顶元素弹出。top(): 返回堆顶元素。size(): 返回元素个数。empty(): 返回是否非空。modify(point_iterator, const key): 把迭代器位置的 key 修改为传入的 key并对底层储存结构进行排序。 erase(point_iterator): 把迭代器位置的键值从堆中擦除。join(__gnu_pbds :: priority_queue other): 把 other 合并到 *this 并把 other 清空。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/88306.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!