题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值。求一棵树中,连通子树值为[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. 设置两个WdatePicker的开始时间小于结束时间,结束时间大于开始时间

    contract_start_date_id为开始时间ID contract_end_date_id为结束时间ID $("#contract_start_date_id").bin ...

  2. VC++中CEdit控件实现回车换行

    1.通过回车Enter换行: 这里要有两个设置 <1>.将控件的属性设置为Mutilines->true; <2>.将控件的另一个属性设置为Want return-> ...

  3. python3.4 百度API接口

    # -*- coding: utf-8 -*- import urllib.request, json url = 'http://apis.baidu.com/netpopo/illegaladdr ...

  4. 分页技巧__设计分页用的QueryHelper辅助对象

    分页技巧__设计分页用的QueryHelper辅助对象 FROM 必须 实体名 WHERE  可选 条件1 AND 条件2 AND ... 条件n ORDER BY 可选 属性1, 属性2, ... ...

  5. 机器学习(Machine Learning)

    机器学习(Machine Learning)是一门专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能的学科.

  6. windows系统添加服务命令

    管理员身份进入cmd sc create TestSvr binPath= D:\Program Files\test.exe start= auto

  7. JAVA上百实例源码网站

    JAVA源码包1JAVA源码包2JAVA源码包3JAVA源码包4 JAVA开源包1 JAVA开源包2 JAVA开源包3 JAVA开源包4 JAVA开源包5 JAVA开源包6 JAVA开源包7 JAVA ...

  8. height:calc(100% - 40px)

    在移动端开发的过程中,常常会遇到头部高度是40px,而内容页是除去头部,占满视窗的整个高度,有时候是用js来处理,现在用css的calc是非常方便的: .container{ height: calc ...

  9. centos7上开启路由转发

    CentOS7 开启路由转发 2018-03-27   09:18:14 1.临时开启,(写入内存,在内存中开启) echo "1" > /proc/sys/net/ipv4 ...

  10. 【BZOJ2879】[Noi2012]美食节 动态加边网络流

    [BZOJ2879][Noi2012]美食节 Description CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食 ...