题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值。求一棵树中,连通子树值为[0,m)的个数。

分析:

设\(dp[i][j]\)为根为i,值为j的子树的个数。

则\(dp[i][j\oplus k] = dp[i][j\oplus k] +dp[i][j] * dp[v][k]\) ,但暴力枚举\(dp[i][j] * dp[v][k]\),每次的复杂度是\(O(M^2)\)的,总的复杂度将是\(O(NM^2)\),N和M都是1e3,不行。

实际上每次要求的,是个异或的卷积。可以用FWT来将复杂度优化至\(O(NMlogM)\)。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = (1<<10)+5;
typedef long long LL;
const int mod= 1e9+7;
LL dp[1005][MAXN];
LL ans[MAXN];
LL a[1005];
int N,M;
LL qpow(LL a,LL n)
{
LL res=1;
while(n){
if(n &1) res = res* a%mod;
a = a*a %mod;
n>>=1;
}
return res;
}
LL rev2 = qpow(2,mod-2); void FWT(LL a[] ,int n){
for (int d = 1 ; d < n ; d <<= 1){
for (int m = d << 1 ,i = 0;i < n ; i+=m){
for (int j = 0 ; j < d ; j++){
LL x = a[i+j],y = a[i+j+d];
a[i+j] = (x+y)%mod,a[i+j+d] = (x-y+mod)%mod; //取模
}
}
}
} void UFWT(LL a[],int n){
for (int d = 1 ; d < n ; d<<=1){
for (int m = d <<1, i = 0; i < n; i+=m){
for (int j = 0 ; j < d ; j++){
LL x = a[i+j],y = a[i+j+d];
a[i+j] = (x+y)*rev2%mod,a[i+j+d] = ((x-y)*rev2%mod + mod) % mod; //取模的情况
}
}
}
}
void solve(LL a[],LL b[],int n){
FWT(a,n);
FWT(b,n);
for (int i = 0 ; i<n ; i++)
a[i]=a[i]*b[i] %mod; //取模
UFWT(a,n);
} struct Edge{
int v,next;
}edges[2005];
int head[1005],tot;
void init(){
tot = 0;
memset(head,-1,sizeof(head));
} void AddEdge(int u,int v)
{
edges[tot] = (Edge){v,head[u]};
head[u] = tot++;
}
LL tmp[MAXN]; void dfs(int u,int fa)
{
dp[u][a[u]] = 1;
for(int i=head[u];~i;i=edges[i].next){
int v = edges[i].v;
if(v== fa) continue;
dfs(v,u);
for(int i=0;i<M;++i){
tmp[i] = dp[u][i];
}
solve(dp[u],dp[v],M);
for(int i=0;i<M;++i){
dp[u][i] = (dp[u][i] + tmp[i])%mod; //将之前
}
}
for(int i=0;i<M;++i){
ans[i] = (ans[i]+ dp[u][i]) %mod;
}
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T; scanf("%d",&T);
while(T--){
init();
memset(dp,0,sizeof(dp));
memset(ans,0,sizeof(ans));
scanf("%d %d",&N, &M);
for(int i=1;i<=N;++i){
scanf("%lld",&a[i]);
}
for(int i=1,u,v;i<=N-1;++i){
scanf("%d %d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
dfs(1,-1);
for(int i=0;i<M;++i){
printf("%lld%c",ans[i],i==M-1?'\n':' ');
}
}
return 0;
}

HDU - 5909 Tree Cutting (树形dp+FWT优化)的更多相关文章

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

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

  2. HDU.5909.Tree Cutting(树形DP FWT/点分治)

    题目链接 \(Description\) 给定一棵树,每个点有权值,在\([0,m-1]\)之间.求异或和为\(0,1,...,m-1\)的非空连通块各有多少个. \(n\leq 1000,m\leq ...

  3. hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...

  4. HDU 5909 Tree Cutting 动态规划 快速沃尔什变换

    Tree Cutting 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5909 Description Byteasar has a tree T ...

  5. [poj3107/poj2378]Godfather/Tree Cutting树形dp

    题意:求树的重心(删除该点后子树最大的最小) 解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次dp求每个子树的节点个数,第二次dp求解答案即可. 此题一开始一直T,后 ...

  6. POJ 2378.Tree Cutting 树形dp 树的重心

    Tree Cutting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4834   Accepted: 2958 Desc ...

  7. HDU 5909 Tree Cutting(FWT+树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5909 [题目大意] 给出一棵树,其每棵连通子树的价值为其点权的xor和, 问有多少连通子树的价值为 ...

  8. poj 2378 Tree Cutting 树形dp

    After Farmer John realized that Bessie had installed a "tree-shaped" network among his N ( ...

  9. hdu 5909 Tree Cutting —— 点分治

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治,每次的 rt 是必选的点: 考虑必须选根的一个连通块,可以DP,决策就是在每个子树中决定选不 ...

随机推荐

  1. RabbitMQ之Queues-5

    工作队列的主要任务是:避免立刻执行资源密集型任务,然后必须等待其完成.相反地,我们进行任务调度:我们把任务封装为消息发送给队列.工作进行在后台运行并不断的从队列中取出任务然后执行.当你运行了多个工作进 ...

  2. python+selenium之简单介绍继承

    python+selenium之简单介绍继承 一.此例简单的介绍一下继承 1.面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制.继承完全可以理解成类之间的类型和子类型 ...

  3. 解决项目导入dubbo依赖项目报红叉问题

    1.maven+ssm项目导入dubbo依赖 项目报错如下 2.出错原因在于dubbo依赖低版本的spring和低版本netty,准备通过maven的依赖管理将依赖传递过来的低版本的spring和ne ...

  4. Java知识点梳理——装箱和拆箱

    1.前言:Java是典型的面向对象编程语言,但其中有8种基本数据类型不支持面向对象编程,基本数据类型不具备对象的特性,没有属性和方法:Java为此8种基本数据类型设计了对应的类(包装类),使之相互转换 ...

  5. fopen与读写的标识r,r+,rb+,rt+,w+.....

    FILE * fopen(const char * path,const char * mode); 参数mode字符串则代表着流形态. mode有下列几种形态字符串: r 打开只读文件,该文件必须存 ...

  6. python--base64

    import base64import os # base64,参数为文件路径名def file_base64(filepath): if os.path.isfile(filepath): with ...

  7. hdu1568&&hdu3117 求斐波那契数前四位和后四位

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1568 题意:如标题所示,求斐波那契数前四位,不足四位直接输出答案 斐波那契数列通式: 当n<=2 ...

  8. JavaScript自定义函数

    js对象转成用&拼接的请求参数(转) var parseParam=function(param, key){ var paramStr=""; if(param inst ...

  9. HTML 之轮播图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 剑指Offer——按之字形顺序打印二叉树

    题目描述: 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 分析: 我们都知道二叉树的层次遍历用的是队 ...