11月1日模拟赛题解

T1 猴猴吃苹果

对深度进行二次排序,并深搜就可以了。

T2 猴猴吃香蕉

题意:有(n)个香蕉,每个香蕉有一个甜度值,求有多少种方法使得甜度值的乘积恰好等于(K)

(1<=n<=1000,1<=k<=1e8)

解法:

(0/1)背包

但发现空间存不下,所以我们选择用(map)进行(dp),注意到(dp)时背包空间的枚举,枚举的空间必须是(K)的因数,而(K)的因数个数大概在(sqrt K)(sqrt [3] K)之间(对于(10^{18})范围内的数,约数个数最多约为(10^5))。时间复杂度理论最差为(10^8)左右,但实际上只有(10^7)左右

T3 猴猴的比赛

题意:猴猴和猩猩比赛爬树,两棵树的节点数都为(n),每棵树的根节点都为节点(1),对于一对满足要求的节点((u,v)),在两棵树中,(v)的深度都在(u)的子树中。求出共有多少对节点满足要求。

(1<=n<=100000)

解法:

(dfs)序 + 线段树区间修改,单点查询

对于(1e5)的数据范围,(n^2)的做法显然是无法通过的,所以我们考虑(nlogn)的做法。

我们考虑如何判断一个点(v)在另一棵树中也在(u)的子节点中,我们先深搜一遍另一棵树,求出(dfs)序数组(dfn)和子树大小数组(size)可以发现当满足(dfn[u]le dfn[v]le dfn[u] + size[u]-1)时,节点(v)在节点(u)的子树中。

我们考虑如何利用(dfs)序的连续性,用线段树解决这个问题。我们一开始的想法是先把每个点子树中的点的(dfs)序在线段树中的下标所对应的值区间修改(1),然后在回溯时把它区间修改(0),但我们考虑到树上进行回溯时只能把父节点的值给回溯掉,所以我们选择在往下深搜时把每个点所对应的子树的(dfs)序下标在线段树中全部区间修改(1),然后访问到一个点时,单点查询每个点的(dfs)序在线段树中所对应的值即可,回溯时区间修改(1)即可。

原文地址:https://www.cnblogs.com/Akaina/p/11805882.html