Prufer 序列
Prufer 序列
Prufer 序列可以将一个带标号
对树建立 Prufer 序列
Prufer 是这样建立的:每次选择一个编号最小的叶结点并删掉它,然后在序列中记录下它连接到的那个结点。重复
线性构造
线性构造的本质就是维护一个指针指向我们将要删除的结点。首先发现,叶结点数是非严格单调递减的。要么删一个,要么删一个得一个。
过程
于是我们考虑这样一个过程:维护一个指针
- 删除
指向的结点,并检查是否产生新的叶结点。 - 如果产生新的叶结点,假设编号为
,我们比较 的大小关系。如果 ,那么不做其他操作;否则就立刻删除 ,然后检查3. 删除 后是否产生新的叶结点,重复 步骤,直到未产生新节点或者新节点的编号 。
让指针 自增直到遇到一个未被删除叶结点为止;
性质
循环上述操作
- 如果
,则反正 往后扫描都会扫到它,于是不做操作; - 如果
,因为 原本就是编号最小的,而 比 还小,所以 就是当前编号最小的叶结点,优先删除。删除 继续这样的考虑直到没有更小的叶结点。
算法复杂度分析,发现每条边最多被访问一次(在删度数的时侯),而指针最多遍历每个结点一次,因此复杂度是
Prufer 序列的性质
- 在构造完 Prufer 序列后原树中会剩下两个结点,其中一个一定是编号最大的点
。 - 每个结点在序列中出现的次数是其度数减
。(没有出现的就是叶结点)
用 Prufer 序列重建树
重建树的方法是类似的。根据 Prufer 序列的性质,我们可以得到原树上每个点的度数。然后你也可以得到编号最小的叶结点,而这个结点一定与 Prufer 序列的第一个数连接。然后我们同时删掉这两个结点的度数。
每次我们选择一个度数为
线性时间重建树
同线性构造 Prufer 序列的方法。在删度数的时侯会产生新的叶结点,于是判断这个叶结点与指针
code
#include<bits/stdc++.h>
#define il inline
#define cs const
#define ri register
using namespace std;
namespace Q{
il int rd(){
ri int x=0;ri bool f=0;ri char c=getchar();
while(!isdigit(c)) f|=(c==45),c=getchar();
while(isdigit(c)) x=x*10+(c^48),c=getchar();
return f?-x:x;
}
il void wt(long long x){
if(x<0) x=-x,putchar(45);
if(x>=10) wt(x/10);
return putchar(x%10|48),void();
}
} using namespace Q;
cs int N=5e6+1;
namespace ope{
int p[N],f[N],deg[N];
il long long getp(int n){
ri long long as=0;
for(ri int i=1;i<n;++i){
f[i]=rd(),deg[f[i]]++;
}
for(ri int i=1,j=1;i<n-1;++i,++j){
while(deg[j]) ++j; p[i]=f[j];
while(i<n-1&&(!--deg[p[i]])&&p[i]<j){
p[i+1]=f[p[i]],++i;
}
}
for(ri int i=1;i<n-1;++i) as^=1ll*i*p[i];
return as;
}
il long long getf(int n){
ri long long as=0;
for(ri int i=1;i<n-1;++i){
p[i]=rd(),deg[p[i]]++;
} p[n-1]=n;
for(ri int i=1,j=1;i<n;++i,++j){
while(deg[j]) ++j; f[j]=p[i];
while(i<n&&(!--deg[p[i]])&&p[i]<j){
f[p[i]]=p[i+1],++i;
}
}
for(ri int i=1;i<n;++i) as^=1ll*i*f[i];
return as;
}
} using namespace ope;
signed main(){
ri int n=rd(),m=rd();
m==1?wt(getp(n)):wt(getf(n));
return 0;
}
I went to the woods because I wanted to live deliberately, I wanted to live deep and suck out all the marrow of life, and not when I had come to die, discover that I had not live.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】