题目大意
给定一棵
n
个节点的树,每个点有权值
定义一棵树的权值为所有点权异或和。
现在对于
[0,m)
的所有整数
k
,请统计出这棵树有多少个联通子树的权值为
联通子树:树的一个联通子图(显然它也是一棵树)
一个测试点
T
组数据。
保证
m
是
题目分析
Solution 1
考虑如果我们确定某个点是一定要选取的,那么我们将其作为根。
那么树中一个点如果选了,它的父亲一定要被选取。
这个树形依赖关系是不是特别熟悉?对了,就是和[JSOI2016]最佳团队类似的模型。
按照
DFS
序
dp
,使用
fi,j
表示
i
一定要选,异或和为
但是一次
dp
是
O(nm)
的,难道我们要做
n
次?而且这样还会有重点。
可以发现一个点如果考虑过,那么就可以将问题分配到它的几个子树来分治了。这个就是经典的点分治,每次选取重心
时间复杂度
O(nmlog2n)
。
很不错的一个思想。
Solution 2
把
1
作为树根,然后每个联通子树肯定有且仅有一个最高点。
设
这是标准的异或卷积形式,可以使用 FWT 在 mlog2m 时间内计算出来。
我们会计算 O(n) 次(边数) FWT ,总时间复杂度 O(nmlog2m) 。
这个方法比较显然,但是像我这样的不会 FWT 的人在比赛时虽然是想出来了也无能为力。