\(\text{Prufer}\)序列,是树与序列的一种双射。

构建过程:

  • 每次找到一个编号最小的叶子节点\(Leaf\),将它删掉,并将它所连接的点的度数\(-1\),且加入\(\text{Prufer}\)序列。

  • 重复上述步骤,直到只剩下两个点。

实现:

考虑如何实现。

最朴素的显然每次暴力找,复杂度\(O(n^2).\)显然不够优秀。

用堆来维护节点,显然可以做到\(O(n\log n).\)

考虑线性实现:维护一个指针,每次指向编号最小的叶节点。删除之后,如果新产生了叶节点并且编号要比指针编号小,则加入\(\text{Prufer}\)序列,继续删除。否则自增到下一个叶节点。

指针只会增加,最多增加\(O(n)次\),时间复杂度即为\(O(n).\)

Rebuild重建

若已知\(\text{Prufer}\)序列,如何重建树?

先通过\(\text{Prufer}\)序列将每一个元素的度\((\text{Deg})\)还原。

同样地,维护一个指针,每次指向编号最小的叶子节点,并把它与当前\(\text{Prufer}\)序列的第一个元素相连。将两个元素的度都减一,并继续找新产生的\(Leaf\),同\(\text{Prufer}\)序列的构建过程。

时间复杂度同样是\(O(n).\)

用处:

  • 凯莱定理:\(n\)个点的完全图生成树个数为\(n^{n-2}.\)
  • 用来造树的数据
  • 推一堆计数式子

例题

代码实现:

下面是模板代码,用了\(\text{fread.}\)

#include<bits/stdc++.h>
using namespace std;
int n,m,f[5000010],p[5000010],d[5000010];
long long ans;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int read(){
int s=0,w=1;
char ch=gc();
while(!isdigit(ch)){
if(ch=='-')w=-1;
ch=gc();
}
while(isdigit(ch)){
s=s*10+ch-'0';
ch=gc();
}
return w==-1?-s:s;
}
}
using namespace IO;
inline void Turn_Prufer(){
for(int i=1;i<n;++i)f[i]=read(),++d[f[i]];
//j为指针
for(int i=1,j=1;i<n-1;++i,++j){
while(d[j])++j;p[i]=f[j];//找到第一个deg为0的点,即为叶子,删掉,把它相连的点加到Prufer里
while(i<n-1&&!--d[p[i]]&&p[i]<j)p[i+1]=f[p[i]],++i;//如果Prufer还没找完,并且删掉它爹(这里新产生的点就是p[i])的度数后也成为叶子,且它的编号要小,此处的p[i]就是上一个点(j)的爹
}
for(int i=1;i<n-1;++i)ans^=1ll*i*p[i];
}
inline void Turn_Father(){
for(int i=1;i<n-1;++i)p[i]=read(),++d[p[i]];
p[n-1]=n;
for(int i=1,j=1;i<n;++i,++j){
while(d[j])++j;f[j]=p[i];
while(i<n&&!--d[p[i]]&&p[i]<j)f[p[i]]=p[i+1],++i;//p[i]就是新产生的点,根据Prufer逆向构造即可
}
for(int i=1;i<n;++i)ans^=1ll*i*f[i];
}
inline void write(long long A){
if(A<0)putchar('-'),A=-A;
if(A>9)write(A/10);
putchar(A%10+'0');
}
int main(){
n=read(),m=read();
if(m==1)Turn_Prufer();
else Turn_Father();
write(ans);
return 0;
}

浅谈Prufer序列的更多相关文章

  1. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  2. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

  3. 浅谈Oracle事务【转载竹沥半夏】

    浅谈Oracle事务[转载竹沥半夏] 所谓事务,他是一个操作序列,这些操作要么都执行,要么都不执行,是一个不可分割的工作单元.通俗解释就是事务是把很多事情当成一件事情来完成,也就是大家都在一条船上,要 ...

  4. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  5. [转]浅谈https\ssl\数字证书

    浅谈https\ssl\数字证书 http://www.cnblogs.com/P_Chou/archive/2010/12/27/https-ssl-certification.html 全球可信的 ...

  6. 浅谈c#枚举

    结构中的成员可以赋值,枚举呢....是取值,只读的 以下情况可以考虑将类创建为结构:(1)如果一个类其中的字段非常少,所有字段占用的内存总量不超过8.16字节:(2)如果一个类中的字段都是值类型: 关 ...

  7. C++ STL中的常用容器浅谈

    STL是C/C++开发中一个非常重要的模板,而其中定义的各种容器也是非常方便我们大家使用.下面,我们就浅谈某些常用的容器.这里我们不涉及容器的基本操作之类,只是要讨论一下各个容器其各自的特点.STL中 ...

  8. 浅谈Base64编码

    浅谈Base64编码 我打赌当你见到Base64这个词的时候你会觉得在哪里见过,因为在你能够上网看到这篇文章的时候你已经在后台使用它了.如果您对二进制数有所了解,你就可以开始读它了. 打开一封Emai ...

  9. 浅谈 Java 主流开源类库解析 XML

    在大型项目编码推进中,涉及到 XML 解析问题时,大多数程序员都不太会选用底层的解析方式直接编码. 主要存在编码复杂性.难扩展.难复用....,但如果你是 super 程序员或是一个人的项目,也不妨一 ...

随机推荐

  1. F - 丘 (欧拉函数)

    Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his own ...

  2. Redis适配采坑记

    Redis适配采坑记 相对于其他的适配,Redis可以说是非常简单的其中只发现一个坑 问题一: 问题描述: redis认证失败 问题详解: redis连接配置时,本地需要采用password属性,远程 ...

  3. String字符串的最大长度是多少?

    在学习和开发过程中,我们经常会讨论 short ,int 和 long 这些基本数据类型的取值范围,但是对于 String 类型我们好像很少注意它的"取值范围".那么对于 Stri ...

  4. Agumaster 改善了pagination

    页面越来越完善了.

  5. flutter vscode 安卓打包apk文件

    配置 VSCode默认是没有使用密钥签名的,往往我们在正式项目中是需要签名的.那就创建好了...所以需要自己创建并使用密钥签名 步骤一 创建密钥库 执行以下命令: keytool -genkey -v ...

  6. java中整型、浮点型、char型扩展

    怎么区分是什么进制? 二进制:0b开头,eg: int i = 0b10; 八进制:0开头,eg: int k = 010; 十进制: 十六进制:0x开头,eg: int j = 0x10; 浮点数类 ...

  7. latex tips

    latex tips  latex 插入图片 主要是插入图片位置的问题,代码中的  bb=   决定了插入 fig2.eps 图片的某一方形区域,其中     表示该方形区域的左下角像素坐标是 0 0 ...

  8. RocketMQ的发送模式和消费模式

    前言 小伙伴们大家好啊,王子又来和大家一起闲谈MQ技术了. 通过之前文章的学习,我们已经对RocketMQ的基本架构有了初步的了解,那今天王子就和大家一起来点实际的,用代码和大家一起看看RocketM ...

  9. Vue和d3.js(v4)力导向图force结合使用,v3版本升级v4【一】

    前段时间因为参与项目涉密,所以一直没有更新博客,有些博友给我私信或者留言要部分博文的源码,因为我的电脑更换,demo的源码没有备份 所以无法提供.大家可针对具体问题问我,有空我定会回复的.另外转发文章 ...

  10. oracle之二管理undo

    管理undo(PPT-I-299-309) 7.1 undo的作用(SMON) 使用undo tablespace 存放从datafiles 读出的数据块的前镜像,提供以下四种情况所需要的信息     ...