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 ...
随机推荐
- 【转】ActiveMQ与虚拟通道
郑重提示,本文转载自http://shift-alt-ctrl.iteye.com/blog/2065436 ActiveMQ提供了虚拟通道的特性(Virtual Destination),它允许一个 ...
- 获取table表格的一些不为人知的属性
JS获取表格的简便方法:获取tbody:tBodies 获取thead:tHead 获取tfoot:tFoot 获取行tr:rows 获取列td:cells 使用实例: oTable. ...
- amazeui tab 监听当前选项
$('#contenttab').find('a').on('opened.tabs.amui', function(e) { if(e.target.pathname.indexOf("[ ...
- stm32按键识别
刚写了一个关于stm32单片机的按键识别的程序.目的,同时识别多个按键,并且不浪费cpu的时间. 关于去抖动,以前以为是在按键的时候,手会抖动.通过程序验证,这个确实是误解.这个应该是防止意外干扰.以 ...
- windows socket函数详解
windows socket函数详解 近期一直用第三方库写网络编程,反倒是遗忘了网络编程最底层的知识.因而产生了整理Winsock函数库的想法.以下知识点均来源于MSDN,本人只做翻译工作.虽然很多前 ...
- Windows 小端存储
小端->高高低低(高位存在高地址,低位存在低地址)
- CSS问题:怎么样让鼠标经过按钮的时候发生的状态一直停留在当页呢?
$('p').mouseenter(function(){ $('p').css('background-color','yellow'); }); 只写一个mouseenter的动态效果的话是不能达 ...
- ios ViewController的生命周期分析和基本使用逻辑
按结构可以对iOS的所有ViewController分成两类:1.主要用于展示内容的ViewController,这种ViewController主要用于为用户展示内容,并与用户交互,如UITable ...
- git 常用使用及问题记录
1.打开bash,进入工程根目录(引用whaon的话:是和.classpath和.project同级的目录).PS:我的系统是win7,在bash切换到E的命令是 cd /e: 2.运行 git in ...
- 读书有感——《从毕业生到程序员使用C#开发商业软件》
本来想自己写个读书感悟之类的东西,但是苦于自己语文水平太差,算了,我把里面觉得很赞的内容摘抄下来就好了(学习都是从模仿开始的嘛). 书籍:<从毕业生到程序猿使用C#开发商业软件> 作者:袁 ...