Tree Cutting
Tree Cutting
Byteasar has a tree TTT with nnn vertices conveniently labeled with 1,2,...,n1,2,...,n1,2,...,n. Each vertex of the tree has an integer value viv_ivi.
The value of a non-empty tree TTT is equal to v1⊕v2⊕...⊕vnv_1\oplus v_2\oplus ...\oplus v_nv1⊕v2⊕...⊕vn, where ⊕\oplus⊕ denotes bitwise-xor.
Now for every integer kkk from [0,m)[0,m)[0,m), please calculate the number of non-empty subtree of TTT which value are equal to kkk.
A subtree of TTT is a subgraph of TTT that is also a tree.
The first line of the input contains an integer T(1≤T≤10)T(1\leq T\leq10)T(1≤T≤10), denoting the number of test cases.
In each test case, the first line of the input contains two integers n(n≤1000)n(n\leq 1000)n(n≤1000) and m(1≤m≤210)m(1\leq m\leq 2^{10})m(1≤m≤210), denoting the size of the tree TTT and the upper-bound of vvv.
The second line of the input contains nnn integers v1,v2,v3,...,vn(0≤vi<m)v_1,v_2,v_3,...,v_n(0\leq v_i < m)v1,v2,v3,...,vn(0≤vi<m), denoting the value of each node.
Each of the following n−1n-1n−1 lines contains two integers ai,bia_i,b_iai,bi, denoting an edge between vertices aia_iai and bi(1≤ai,bi≤n)b_i(1\leq a_i,b_i\leq n)bi(1≤ai,bi≤n).
It is guaranteed that mmm can be represent as 2k2^k2k, where kkk is a non-negative integer.
For each test case, print a line with mmm integers, the iii-th number denotes the number of non-empty subtree of TTT which value are equal to iii.
The answer is huge, so please module 109+710^9+7109+7.
2
4 4
2 0 1 3
1 2
1 3
1 4
4 4
0 1 3 1
1 2
1 3
1 4
3 3 2 3
2 4 2 3 分析:dp[i][j]表示以i为根异或值为j的方案数;
在加入i的儿子x的子树方案时,dp[i][j]=dp[i][j]+dp[i][k]*dp[x][t](k^t=j);
其中dp[i][k]*dp[x][t](k^t=j)的复杂度为n²,可以用异或卷积加速到nlogn;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define vi vector<int>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define rev (mod+1)/2
#define inf 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
using namespace std;
const int maxn=1e3+;
int n,m,k,t,a[maxn],dp[maxn][maxn],tmp[maxn],ans[maxn];
vi e[maxn];
void fwt(int *a,int n)
{
for(int d=;d<n;d<<=)
for(int m=d<<,i=;i<n;i+=m)
for(int j=;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;
}
}
void ufwt(int *a,int n)
{
for(int d=;d<n;d<<=)
for(int m=d<<,i=;i<n;i+=m)
for(int j=;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;
}
}
void solve(int *a,int *b,int n)
{
fwt(a,n);
fwt(b,n);
for(int i=;i<n;i++)a[i]=1LL*a[i]*b[i]%mod;
ufwt(a,n);
}
void dfs(int now,int pre)
{
dp[now][a[now]]=;
for(int x:e[now])
{
if(x==pre)continue;
dfs(x,now);
for(int i=;i<m;i++)
tmp[i]=dp[now][i];
solve(dp[now],dp[x],m);
for(int i=;i<m;i++)
dp[now][i]=(dp[now][i]+tmp[i])%mod;
}
for(int i=;i<m;i++)
ans[i]=(ans[i]+dp[now][i])%mod;
}
int main()
{
int i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
rep(i,,n)
{
scanf("%d",&a[i]),e[i].clear();
rep(j,,m-)dp[i][j]=;
}
rep(i,,m-)ans[i]=;
rep(i,,n-)
{
scanf("%d%d",&j,&k);
e[j].pb(k),e[k].pb(j);
}
dfs(,);
rep(i,,m-)printf("%d%c",ans[i],i<m-?' ':'\n');
}
//system ("pause");
return ;
}
Tree Cutting的更多相关文章
- 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)
Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...
- BZOJ3391: [Usaco2004 Dec]Tree Cutting网络破坏
3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 47 Solved: 37[ ...
- BZOJ 3391: [Usaco2004 Dec]Tree Cutting网络破坏( dfs )
因为是棵树 , 所以直接 dfs 就好了... ---------------------------------------------------------------------------- ...
- 3391: [Usaco2004 Dec]Tree Cutting网络破坏
3391: [Usaco2004 Dec]Tree Cutting网络破坏 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 76 Solved: 59[ ...
- hdu 5909 Tree Cutting [树形DP fwt]
hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...
- POJ 2378.Tree Cutting 树形dp 树的重心
Tree Cutting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4834 Accepted: 2958 Desc ...
- 【HDU5909】Tree Cutting(FWT)
[HDU5909]Tree Cutting(FWT) 题面 vjudge 题目大意: 给你一棵\(n\)个节点的树,每个节点都有一个小于\(m\)的权值 定义一棵子树的权值为所有节点的异或和,问权值为 ...
- HDU 5909 Tree Cutting 动态规划 快速沃尔什变换
Tree Cutting 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5909 Description Byteasar has a tree T ...
- POJ 2378 Tree Cutting 3140 Contestants Division (简单树形dp)
POJ 2378 Tree Cutting:题意 求删除哪些单点后产生的森林中的每一棵树的大小都小于等于原树大小的一半 #include<cstdio> #include<cstri ...
随机推荐
- 前台图片上传展示JS(单张图片展示)
<script type="text/javascript"> //下面用于多图片上传预览功能 function setImagePreviews(aval ...
- POJ 2240 Arbitrage(SPFA+邻接矩阵)
( ̄▽ ̄)" #include<iostream> #include<cstdio> #include<cmath> #include<algori ...
- sql新建数据库表,及添加多个主键
create table tb_Modules(module_Id int identity(1,1) primary key, (自增)model_Name varchar(50) not nul ...
- HDU 2209 翻纸牌游戏(DFS)
题目链接 Problem Description 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌.但是麻烦 ...
- webpy 开发环境搭建问题之Mysql-python安装
关于python核心编程已经看了差不多,准备搞些框架方面的学习,本来想打算看看Django的,但是朋友推荐先看看轻量级的flask或者webpy的开发,所以晚上回来,搭建下开发环境(PS:搭建过程中由 ...
- 移动端touch事件获取clientX, clientY
目有个交互需要实现手指滑动的交互,pc端使用mousedown,mousemove,mouseup监听实现. 但在ios设备上mousemove是不好监听的,同类的方法是touchstart,touc ...
- 查找一个数组中最小的前n项
/****************************************************************** find the biggest x number in a s ...
- cookie机制和session机制的区别(面试题)
一.cookie机制和session机制的区别 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案. 同时我们也看到,由于才服务器端保持状态的 ...
- GitHub使用指导
GitHub 用过Git的小伙伴想必都知道GitHub是个什么东东,我这里就简单介绍一下吧.Git是一个分布式的版本控制系统,而GitHub可以托管各种Git库,并提供一个Web界面,方便查看Git库 ...
- POJ 3279 Fliptile[二进制状压DP]
题目链接[http://poj.org/problem?id=3279] 题意:给出一个大小为M*N(1 ≤ M ≤ 15; 1 ≤ N ≤ 15) 的图,图中每个格子代表一个灯泡,mp[i][j] ...