HDU 5909 Tree Cutting (树形dp+FWT)
来源:互联网 发布:怎么切换mac系统 编辑:程序博客网 时间:2024/06/06 01:56
Tree Cutting
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/131072 K (Java/Others)Total Submission(s): 183 Accepted Submission(s): 77
Problem Description
Byteasar has a tree T with n vertices conveniently labeled with 1,2,...,n . Each vertex of the tree has an integer value vi .
The value of a non-empty treeT is equal to v1⊕v2⊕...⊕vn , where ⊕ denotes bitwise-xor.
Now for every integerk from [0,m) , please calculate the number of non-empty subtree of T which value are equal to k .
A subtree ofT is a subgraph of T that is also a tree.
The value of a non-empty tree
Now for every integer
A subtree of
Input
The first line of the input contains an integerT(1≤T≤10) , denoting the number of test cases.
In each test case, the first line of the input contains two integersn(n≤1000) and m(1≤m≤210) , denoting the size of the tree T and the upper-bound of v .
The second line of the input containsn integers v1,v2,v3,...,vn(0≤vi<m) , denoting the value of each node.
Each of the followingn−1 lines contains two integers ai,bi , denoting an edge between vertices ai and bi(1≤ai,bi≤n) .
It is guaranteed thatm can be represent as 2k , where k is a non-negative integer.
In each test case, the first line of the input contains two integers
The second line of the input contains
Each of the following
It is guaranteed that
Output
For each test case, print a line withm integers, the i -th number denotes the number of non-empty subtree of T which value are equal to i .
The answer is huge, so please module109+7 .
The answer is huge, so please module
Sample Input
24 42 0 1 31 21 31 44 40 1 3 11 21 31 4
Sample Output
3 3 2 32 4 2 3
Source
BestCoder Round #88
Recommend
wange2014 | We have carefully selected several similar problems for you: 5932 5931 5930 5929 5928
题意:
有一棵n个点的无根树,节点依次编号为1到n,其中节点i的权值为v。
定义一棵树的价值为它所有点的权值的异或和。
现在对于每个[0,m)的整数k,请统计有多少T的非空连通子树的价值等于k。
一棵树T的连通子树就是它的一个连通子图,并且这个图也是一棵树。
定义一棵树的价值为它所有点的权值的异或和。
现在对于每个[0,m)的整数k,请统计有多少T的非空连通子树的价值等于k。
一棵树T的连通子树就是它的一个连通子图,并且这个图也是一棵树。
题解:设dp[ u ][ i ]表示 u 为根的数,异或后得到 i 的方案数。
转移是个异或卷积的形式,可以用FWT加速计算。
时间复杂度:O(n*m*logm).
那么对于一个状态dp[u][i]我们有加入u的一个子树x之后的新的状态dp[u"][ i ]的值dp[u"][ i ]=dp[u][v]+ (异或卷积)∑(i xor j)dp[u][ i ]*dp[x][ j ]。
转移是个异或卷积的形式,可以用FWT加速计算。
时间复杂度:O(n*m*logm).
那么对于一个状态dp[u][i]我们有加入u的一个子树x之后的新的状态dp[u"][ i ]的值dp[u"][ i ]=dp[u][v]+ (异或卷积)∑(i xor j)dp[u][ i ]*dp[x][ j ]。
AC代码:
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector>using namespace std;typedef long long LL;const int N=1e3+100; //2^10const int mod=1e9+7;const int rev=(mod+1)>>1;//dp[u][i]表示 u 为根的数,异或后得到 i 的方案数 int val[N], dp[N][N],ans[N];int temp[N];int len;int n,m;struct Edge{int from,to;}edge[2*N];int cnt;int head[N];vector<int> V[2*N]; //void addedge(int u,int v)//{//edge[cnt].from=v; edge[cnt].to=head[u]; head[u]=cnt++;//edge[cnt].from=u; edge[cnt].to=head[v]; head[v]=cnt++;//}void FWT(int 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++){ int x=a[i+j],y=a[i+j+d]; a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod; //xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod; //and:a[i+j]=x+y; //or:a[i+j+d]=x+y; }}void UFWT(int 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++){ int x=a[i+j],y=a[i+j+d]; a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod; //xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2; //and:a[i+j]=x-y; //or:a[i+j+d]=y-x; }}void solve(int a[],int b[],int n){ FWT(a,n); FWT(b,n); for(int i=0;i<n;i++) a[i]=1LL*a[i]*b[i]%mod; UFWT(a,n);}void dfs(int u,int fa){dp[u][val[u]]=1;//自己与自己异或后为 0 的方案数 for(int i=0;i<V[u].size();i++){int v = V [u][i];if(v==fa) continue;dfs(v,u);for(int i=0;i<m;i++) temp[i]=dp[u][i];solve(dp[u],dp[v],m); //当前dp[u]的所有值与dp[v]的所有值异或的结果for(int i=0;i<m;i++) dp[u][i]=(dp[u][i]+temp[i])%mod;}for(int i=0;i<m;i++) ans[i]=(ans[i]+dp[u][i])%mod;}int main(){int t,u,v; scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);memset(ans,0,sizeof(ans));memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++) V[i].clear(); for(int i=1;i<=n;i++) scanf("%d",&val[i]);for(int i=1;i<n;i++){scanf("%d%d",&u,&v);//addedge(u,v);//addedge(v,u);V[u].push_back(v);V[v].push_back(u);}dfs(1,0);for(int i=0;i<m-1;i++)printf("%d ",ans[i]);printf("%d\n",ans[m-1]);}return 0;}
2 0
- [树形DP FWT] HDU 5909 Tree Cutting
- HDU 5909 Tree Cutting (树形dp+FWT)
- HDU 5909 Tree Cutting (点分治+树形DP|FWT+树形DP)
- HDU 5909 Tree Cutting [树形dp+FWT]【动态规划+数学】
- [树形DP] [FWT] [HDU5909] Tree Cutting
- HDU 5909 Tree Cutting 树形DP+快速沃尔什变换
- Hdu 5909 Tree Cutting(fwt优化异或卷积)
- Tree Cutting (树形DP)
- Tree Cutting 树形dp
- poj 2378 Tree Cutting(树形dp)
- POJ 2378 Tree Cutting(树形DP)
- POJ 2378 Tree Cutting (简单树形DP、删点)
- Tree Cutting (树形dp+树的重心变形)
- Tree Cutting (树形dp + 树的重心问题变形)
- POJ--2378--Tree Cutting--树形DP
- (简单) 树形dp POJ 2378 Tree Cutting
- 【TOJ 3522.】Tree cutting【树形DP】
- poj 2378 Tree Cutting (树形dp)
- 2016秋招
- 编译错误导致浪费10多分钟, 编译错误的提示:xxx does not name a type xxx
- 加拿大留学热门专业解读之计算机专业
- 本地Eclipse中Tomcat运行测试环境代码
- 剑指offer(11)-包含min函数的栈
- HDU 5909 Tree Cutting (树形dp+FWT)
- java io -- InputStream
- ListView控件相关用法
- 【POJ 3321】【dfs序(讲解)+(树状数组或者线段树)】Apple Tree【给你一颗树,最初每个节点上都有一个苹果,有两种操作单点修改和查询子树的苹果个数】
- 我给程序员新手写简历的一些建议
- git介绍
- 关于远程服务
- 简明 Vim 练级攻略以及基础操作
- 第69篇Chrome扩展USB开发(五)及php