传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5909

【题解】

设$f_{x,i}$表示以$x$节点的子树中,权值为$i$的子树个数,其中$x$必选。

那么有dp方程:$f_{x,i} = \sum_{y = son[x]} f_{x,i} + \sum_{j \oplus k = i}f_{x, j}f_{y, k}$

用FWT优化转移即可,复杂度$O(nmlogm)$。

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 1e3 + , H = + ;
const int mod = 1e9+; int n, L, w[N], inv2;
int f[N][H];
int ans[H];
int head[N], nxt[N + N], to[N + N], tot = ;
inline void add(int u, int v) {
++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
}
inline void adde(int u, int v) {
add(u, v), add(v, u);
} inline int pwr(int a, int b) {
int ret = ;
while(b) {
if(b&) ret = 1ll * ret * a % mod;
a = 1ll * a * a % mod;
b >>= ;
}
return ret;
} int s[H], t[H];
inline void FWT(int *a, int op) {
if(op) {
for (int len = ; len <= L; len<<=) {
int m = len >> ;
for (int *p = a; p != a+L; p += len) {
for (int k=; k<m; ++k) {
int x = p[k], y = p[k+m];
p[k] = 1ll * (x+y) * inv2 % mod;
p[k+m] = 1ll * (x-y+mod) * inv2 % mod;
}
}
}
} else {
for (int len = ; len <= L; len<<=) {
int m = len >> ;
for (int *p = a; p != a+L; p += len) {
for (int k=; k<m; ++k) {
int x = p[k], y = p[k+m];
p[k] = (x+y) % mod;
p[k+m] = (x-y+mod) % mod;
}
}
}
}
} inline void FWT_combine(int *A, int *B) {
for (int i=; i<L; ++i) s[i] = A[i], t[i] = B[i];
FWT(s, ); FWT(t, );
for (int i=; i<L; ++i) s[i] = 1ll * s[i] * t[i] % mod;
FWT(s, );
for (int i=; i<L; ++i) (A[i] += s[i]) %= mod;
} inline void dfs(int x, int fa = ) {
for (int j=; j<L; ++j) f[x][j] = ;
f[x][w[x]] = ;
for (int i=head[x]; i; i=nxt[i]) {
if(to[i] == fa) continue;
dfs(to[i], x);
FWT_combine(f[x], f[to[i]]);
}
for (int j=; j<L; ++j) (ans[j] += f[x][j]) %= mod;
} inline void sol() {
tot = ;
memset(head, , sizeof head);
memset(ans, , sizeof ans);
cin >> n >> L;
for (int i=; i<=n; ++i) scanf("%d", w+i);
for (int i=, u, v; i<n; ++i) {
scanf("%d%d", &u, &v);
adde(u, v);
}
dfs();
printf("%d", ans[]);
for (int i=; i<L; ++i) printf(" %d", ans[i]);
puts("");
} int main() {
int T; cin >> T;
inv2 = pwr(, mod-);
while(T--) sol();
return ;
}

hdu5909 Tree Cutting的更多相关文章

  1. HDU5909 Tree Cutting(树形DP + FWT)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5909 Description Byteasar has a tree T with n ve ...

  2. hdu5909 Tree Cutting 【树形dp + FWT】

    题目链接 hdu5909 题解 设\(f[i][j]\)表示以\(i\)为根的子树,\(i\)一定取,剩余节点必须联通,异或和为\(j\)的方案数 初始化\(f[i][val[i]] = 1\) 枚举 ...

  3. 【HDU5909】Tree Cutting(FWT)

    [HDU5909]Tree Cutting(FWT) 题面 vjudge 题目大意: 给你一棵\(n\)个节点的树,每个节点都有一个小于\(m\)的权值 定义一棵子树的权值为所有节点的异或和,问权值为 ...

  4. 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)

    Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...

  5. BZOJ3391: [Usaco2004 Dec]Tree Cutting网络破坏

    3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 47  Solved: 37[ ...

  6. BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )

    因为是棵树 , 所以直接 dfs 就好了... ---------------------------------------------------------------------------- ...

  7. Tree Cutting

    Tree Cutting Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others) Prob ...

  8. 3391: [Usaco2004 Dec]Tree Cutting网络破坏

    3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 76  Solved: 59[ ...

  9. hdu 5909 Tree Cutting [树形DP fwt]

    hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...

随机推荐

  1. Android - TabHost 选项卡功能用法详解

    TabHost效果图 : 源码下载地址 : http://download.csdn.net/detail/han1202012/6845105        . 作者 :万境绝尘  转载请注明出处  ...

  2. bootstrap列表添加滚动条

    有时候列表中数据过多,导致超出页面,影响视觉感受.这时我们需要添加一个滚动条. 初始状态如图: 代码如下: <ul class="list-group"> <li ...

  3. 【week2】 累计进度条、psp、饼图

    每周例行报告 本周PSP 类别 任务 开始时间 结束时间 被打断时间 总计工作时间 2016年9月9日 读书 构建之法-5.6章 19:00 20:00 0 60min 2016年9月10日 看博客 ...

  4. cmd批处理中set /a和set /p的区别介绍

    在 SET 命令中添加了两个新命令行开关: SET /A expression SET /P variable=[promptString]/p 是让你输入/a 是指定一个变量等于一串运算字符 什么参 ...

  5. [socket编程] 一个服务器与多个客户端之间通信

    转自:http://blog.csdn.net/neicole/article/details/7539444 并加以改进 Server程序: // OneServerMain.cpp #includ ...

  6. [计算机网络] C++模拟telnet登陆SMTP服务发送邮件过程

    在百度文库中的<使用telnet协议收发邮件>,我们可以很清楚地看到如何通过telnet来进行发送邮件,下面是一些需要用到的命令,通过以下命令可以很容易实现邮件发送功能.为了更好地理解其中 ...

  7. 【Python】从1<2<3的语法糖说起

    python有一个很有意思的语法糖你可以直接写1<2<3. 这复合我们通常意义上的数学不等式,但对学过C等语言其实是有疑惑的. 我们知道不等式返回的其实是个Bool值,在C中是1,0因此C ...

  8. 【WCF】WCF 附录 高级主题 配置服务配额设置

    微软产品自带一个“默认安全”方案.这也包括了WCF,意味着WCF中的多种配置可以设置来阻止诸如DOS(拒绝服务访问)攻击.微软为很多基于一个单一计算机的开发环境选择这样的设置.这也意味着默认设置中的一 ...

  9. Codeforces Round #521 Div. 3 玩耍记

    A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...

  10. Mysql 基本语句练习

    一.怎样查看数据库信息? desc 数据库名; 二.怎样查看数据表信息? desc 表名:          //查看表的属性和属性值 或者用select语句: //查看表的行记录信息 select ...