Kth Ancestor 第k个祖先问题
这道题目出自hackerrank的8月月赛的第三题。
题目大意:
先给出一棵树
之后有三种操作分别为:加边,查询,和删除一个节点
查询的时候要给出任意节点x的第k个祖先
每组数据有t个case
每个case边(P)的数量小于等于10^5
每个case的操作的数量(Q)小于等于10^5
题目分析:
一开始拿到这个题目的时候被搞得一头雾水,如果采用普通的暴力的办法,每一个查询需要O(P),总体的复杂度就变成了O(Q*P),铁定TLE…
思考了三天没有什么想法然后搜了一下,发现了这个:
研读了一番之后发现了使用一个神奇的数据结构,使得每一次的查询可以降为long(P)的复杂度,这样问题就迎刃而解了。
这个奇特的数据结构,我这样描述:
对树进行DFS,记录下每一条路径e[i]。
之后开一个node[i]标记每个节点所在的边号(index),以及在该边的深度(depth)还有该点的“父节点”(father 该点所在边的起点e[node[i].index][0]的父节点)。
那么查询的时候Q(x,k)就等于:
k <= node[x].depth 时 return e[node[x].index][node[x].depth-k]
k > node[x].depth 时 return Q(node[x].father,k-1)
之后就是一系列的边界描述,不再赘述了。
第一次写出来的这个代码十分之丑陋,大家见笑了
python3写的


Level ancestorclass node:
def __init__(self,depth = 0,father = -1,index = -1,mark = -2):
self.depth = depth
self.father = father
self.index = index
self.mark = mark
path = []
nodes = [] MAXN = 100000+5 def NEW(x,y):
path.append([y,x])
l = len(path)-1
nodes[y] = node(0,-1,l,-1)
nodes[x] = node(0,y,l,1) def CON(x,y):
if ( nodes[y].mark == 1 ):
nodes[x] = node(nodes[y].depth+1,nodes[y].father,nodes[y].index,1)
nodes[y].mark = 0
path[nodes[y].index].append(x)
elif(( nodes[y].mark == -1 ) & ( len(path[nodes[y].index]) == 1 ) ):
nodes[x] = node(nodes[y].depth+1,nodes[y].father,nodes[y].index,1)
path[nodes[y].index].append(x)
else:
ADD(x)
l = len(path)-1
nodes[x] = node(0,y,l,1) def ADD(x):
path.append([x]) def update(x,y):
if ( ( nodes[x].mark == -2 ) & ( nodes[y].mark == -2 ) ):
NEW(x,y)
elif ( ( nodes[x].mark == -2 ) & ( nodes[y].mark != -2 ) ):
CON(x,y)
elif ( ( nodes[x].mark != -2 ) & ( nodes[y].mark != -2 ) ):
nodes[x].father = y
elif ( ( nodes[x].mark != -2 ) & ( nodes[y].mark == -2 ) ):
ADD(y)
nodes[y] = node(0,-1,len(path)-1,1)
nodes[x].father = y def DEL(x):
path[nodes[x].index].remove(x)
nodes[x] = node() def LOA(x,k):
if ( x == 0 ):
return 0;
if ( nodes[x].mark == -2 ):
return 0
if (nodes[x].depth >= k):
lt = nodes[x].depth - k
if ( path[nodes[x].index][0] == 0 ):
lt = lt+1
return path[nodes[x].index][lt]
if ( nodes[x].depth < k ):
if ( ( nodes[x].father == -1 ) or ( nodes[x].father == 0 ) ):
return 0
t = LOA(nodes[x].father,k-nodes[x].depth-1)
return t def INIT():
global path
global nodes
path = []
nodes = [node() for i in range(0,MAXN)] def build():
n = int(input())
for i in range(0,n):
x,y = input().split(' ')
x = int(x)
y = int(y)
update(x,y)
#print(path) def Q():
n = int(input())
for i in range(0,n):
lt = input().split(' ')
if ( lt[0] == '0' ):
update(int(lt[2]),int(lt[1]))
#print(path)
if ( lt[0] == '1' ):
DEL(int(lt[1]))
if ( lt[0] == '2' ):
print(LOA(int(lt[1]),int(lt[2]))) t = input()
t = int(t)
for i in range(0,t):
INIT()
build()
Q()
以后争取做到学会了就记录下来,这个代码贴给后人鄙视吧
Kth Ancestor 第k个祖先问题的更多相关文章
- Vijos lxhgww的奇思妙想--求K级祖先
给出一棵树求K级祖先.O(N*logN+Q) 更详细的讲解见:https://www.cnblogs.com/cjyyb/p/9479258.html /* 要求k级祖先,我们可以把k拆成" ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- K-th Number(第k大数)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 45710 Accepted: 15199 Ca ...
- Vijos.lxhgww的奇思妙想(k级祖先 长链剖分)
题目链接 https://blog.bill.moe/long-chain-subdivision-notes/ http://www.cnblogs.com/zzqsblog/p/6700133.h ...
- 树链剖分 (求LCA,第K祖先,轻重链剖分、长链剖分)
2020/4/30 15:55 树链剖分是一种十分实用的树的方法,用来处理LCA等祖先问题,以及对一棵树上的节点进行批量修改.权值和查询等有奇效. So, what is 树链剖分? 可以简单 ...
- Find the largest K numbers from array (找出数组中最大的K个值)
Recently i was doing some study on algorithms. A classic problem is to find the K largest(smallest) ...
- 【POJ2985】【Treap + 并查集】The k-th Largest Group
Description Newman likes playing with cats. He possesses lots of cats in his home. Because the numbe ...
- Kth Smallest Element in a BST 解答
Question Given a binary search tree, write a function kthSmallest to find the kth smallest element i ...
- 4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap
国际惯例的题面:这种维护排序序列,严格大于的进行操作的题都很套路......我们按照[0,k],(k,2k],(2k,inf)分类讨论一下就好.显然第一个区间的不会变化,第二个区间的会被平移进第一个区 ...
随机推荐
- C# 调用 MFC DLL
创建项目 创建MFCDLL项目 MFC项目中这么声明 生成dll工程 可以看到库文件的生成目录,保存下来 创建测试用c#项目 我们创建一个按钮调用我们刚才的函数 这边这么调用MFC库的函数入口.这里并 ...
- about hadoop-eclipse-plugin used by IDE
Apache Hadoop Development Tools (HDT) is still in development phase. So, no official distribution of ...
- 查看Oracle表空间使用情况与增大表空间
1,查看表空间使用情况 SELECT D.TABLESPACE_NAME, SPACE || 'M' "SUM_SPACE(M)", BLOCKS "SUM_BLOCKS ...
- 13个小技巧帮你征服Xcode
本文由CocoaChina翻译组成员唧唧歪歪(博客)翻译自David McGraw的博客原文:13 Xcode Tips That Will Help You Conquer Xcode当谈论到iOS ...
- STM32之外部中断控制
一.STM32外部中断 1.STM32外部中断结构图 如上图所示:主要包括四个环节,GPIO.AFIO.EXTI.NVIC.以STM32F103VE(100脚)为例说明硬件模块的数量: GPIO: ...
- 关于textjs的tree带复选框的树
通过查阅一些资料和自己之前了解到的一些相关知识,有时项目中需要用到.话不多说,先看一下效果图: 我写的这人员选择的树,主要是改写了TreePanel,如下代码: ExtendTreePanel.js ...
- 这是从word发的第一篇博客。
喜欢做的事,怎么样都不会厌倦. 以前只知道office功能强大,但不太清楚到底还能干些啥,印象最深的是outlook了,自己也在用,挺好 今天偶然发现,word还能发布博客,真是太惊喜了 这算是一篇实 ...
- Android动画总结#补间动画(Tween Animation/View Animation) #帧动画(Frame Animation/Drawable Animation)#属性动画(PropertyAnimation)
1.共有三种动画,英文名字多种叫法如下 第一种动画:补间动画(Tween Animation/View Animation) 四个:RotateAnimation旋转. AlphaAnimation透 ...
- 关于ADMM的研究(二)
关于ADMM的研究(二) 4. Consensus and Sharing 本节讲述的两个优化问题,是非常常见的优化问题,也非常重要,我认为是ADMM算法通往并行和分布式计算的一个途径:consens ...
- uva 11922 - Permutation Transformer
splay的题: 学习白书上和网上的代码敲的: #include <cstdio> #include <cstring> #include <cstdlib> #i ...