【bzoj3696】化合物 树形dp
2017-07-07 20:29
204 查看
题目描述
首长NOI惨跪,于是去念文化课了。现在,他面对一道化学题。
这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏。这个游戏很蛋疼,我相信你们也没有兴趣听。
由于这个游戏涉及博弈论,因此化竞的同学就要求首长求一个类似SG函数的值。
他们手中有一种非常神奇的化合物,它的分子由N个原子组成(不要在意一个原子可能和及其多个原子成键这个细节)。这个分子构成一个树结构,1号分子为根。 若两个原子i、j到它们的最近公共祖先的距离分别是Li和Lj,定义它们的Aij值为:
Aij=Li xor Lj
题目要求对于每一个k(k∈N),求出两两A值为k的原子对个数。
输入
第一行一个整数N。
接下来N-1行,每行一个整数p,第i行的整数表示第i个原子的父亲为p。
输出
从K=0开始,第k+1行输出两两A值为K的原子对个数,输出到第一个不为零的数为止。
样例输入
3
1
1
样例输出
1
2
题解
树形dp
第一眼看到这题感觉直接上树形dp可能会TLE,然而貌似数据水。
然后随便搞了搞就交上去了, 结果不但没T,而且跑得飞快(CQzhangyu压了压状态然后怒拿rank1)
设f[i][j]表示以i为根的子树中深度为j的节点个数。
考虑答案,枚举x中深度为j的节点和x的儿子s中深度为k的节点,那么显然$ans[(j-deep[x])xor(k-deep[x])]+=f[x][j]*f[s][k]$。
然后再更新x。
上界设的紧一点就可以稳切了。
时间复杂度大概是$O(nh^2)$的。
另外本题亲测不需要开long long
UPD:正解貌似是FWT,然而好像没有暴力快。。。
首长NOI惨跪,于是去念文化课了。现在,他面对一道化学题。
这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博弈论游戏。这个游戏很蛋疼,我相信你们也没有兴趣听。
由于这个游戏涉及博弈论,因此化竞的同学就要求首长求一个类似SG函数的值。
他们手中有一种非常神奇的化合物,它的分子由N个原子组成(不要在意一个原子可能和及其多个原子成键这个细节)。这个分子构成一个树结构,1号分子为根。 若两个原子i、j到它们的最近公共祖先的距离分别是Li和Lj,定义它们的Aij值为:
Aij=Li xor Lj
题目要求对于每一个k(k∈N),求出两两A值为k的原子对个数。
输入
第一行一个整数N。
接下来N-1行,每行一个整数p,第i行的整数表示第i个原子的父亲为p。
输出
从K=0开始,第k+1行输出两两A值为K的原子对个数,输出到第一个不为零的数为止。
样例输入
3
1
1
样例输出
1
2
题解
树形dp
第一眼看到这题感觉直接上树形dp可能会TLE,然而貌似数据水。
然后随便搞了搞就交上去了, 结果不但没T,而且跑得飞快(CQzhangyu压了压状态然后怒拿rank1)
设f[i][j]表示以i为根的子树中深度为j的节点个数。
考虑答案,枚举x中深度为j的节点和x的儿子s中深度为k的节点,那么显然$ans[(j-deep[x])xor(k-deep[x])]+=f[x][j]*f[s][k]$。
然后再更新x。
上界设的紧一点就可以稳切了。
时间复杂度大概是$O(nh^2)$的。
另外本题亲测不需要开long long
UPD:正解貌似是FWT,然而好像没有暴力快。。。
#include <cstdio> #include <cstring> #include <algorithm> #define N 100010 using namespace std; int head , to , next , cnt , f[510] , deep , md , ans[520]; void add(int x , int y) { to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt; } void dfs(int x) { int i , j , k; md[x] = deep[x] , f[deep[x]][x] ++ ; for(i = head[x] ; i ; i = next[i]) { deep[to[i]] = deep[x] + 1 , dfs(to[i]); for(j = deep[x] ; j <= md[x] ; j ++ ) for(k = deep[to[i]] ; k <= md[to[i]] ; k ++ ) ans[(j - deep[x]) ^ (k - deep[x])] += f[j][x] * f[k][to[i]]; for(j = deep[to[i]] ; j <= md[to[i]] ; j ++ ) f[j][x] += f[j][to[i]]; md[x] = max(md[x] , md[to[i]]); } } int main() { int n , i , x; scanf("%d" , &n); for(i = 2 ; i <= n ; i ++ ) scanf("%d" , &x) , add(x , i); dfs(1); for(i = 0 ; ans[i] ; i ++ ) printf("%d\n" , ans[i]); return 0; }
相关文章推荐
- [bzoj3696]化合物_树形dp
- 【BZOJ-3696】化合物 树形DP + 母函数(什么鬼)
- 【BZOJ3696】化合物 树形DP+暴力
- [树形DP 暴力] BZOJ 3696 化合物
- 3696: 化合物|树形DP
- BZOJ 3238: [Ahoi2013]差异 后缀自动机 树形dp
- [BZOJ3572][Hnoi2014]世界树(虚树+树形DP)
- BZOJ 2427 软件安装 树形dp+tarjan
- BZOJ1040 [ZJOI2008]骑士(基环树+树形dp)
- BZOJ 1131 POI2008 Sta 树形DP
- bzoj 4557: [JLoi2016]侦察守卫【树形dp】
- BZOJ3522 POI2014HOT-Hotels(树形dp)
- BZOJ 2097 USACO 2010 Dec Gold Exercise 奶牛健美操 二分答案 树形DP 贪心
- BZOJ_3573_[Hnoi2014]米特运输_树形DP+hash
- 【树形Dp】【JSOI2008】【BZOJ1017魔兽地图DotR】
- bzoj 4007 树形dp
- bzoj4182 shopping [树形dp+点分治]
- bzoj 1060: [ZJOI2007]时态同步 树形dp
- bzoj 2286: [Sdoi2011消耗战 (虚树+树形DP)
- bzoj 3611: [Heoi2014]大工程 (虚树+树形DP)