传送门

题意:

有一棵n个点的无根树,节点依次编号为1到n,其中节点i的权值为vi,
定义一棵树的价值为它所有点的权值的异或和。
现在对于每个[0,m)的整数k,请统计有多少T的非空连通子树的价值等于k。

Sample Input
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
Sample Output
3 3 2 3
2 4 2 3
令f[i][j]表示以i为根的子树中异或和为j的联通块个数,v为i儿子
f[i][j]+=f[i][k]*f[v][l]    (k^l==j)
发现转移其实可以写成这种形式:
$C_i=\sum_{j^k=i}A_j*B_k$
这和卷积有点类似,不过运算改成了异或
这里就要用到FWT(快速沃尔什变换)
就可以做到nlogn转移
转移完后记得在加上原来的f[i][j],因为你可以不选v
复杂度为$O(n^{2}logn)$
卡常,少取模,不要定义long long变量
这题还可以点分治
 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
int next,to;
}edge[];
int num,head[],Mod=1e9+,inv2,tmp[],a[][],ans[],n,m;
int gi()
{
char ch=getchar();
int x=;
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x;
}
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
int qpow(int x,int y)
{
int res=;
while (y)
{
if (y&) res=1ll*res*x%Mod;
x=1ll*x*x%Mod;
y/=;
}
return res;
}
void FWT(int *A,int len)
{int i,j,k;
for (i=;i<m;i<<=)
{
for (j=;j<m;j+=(i<<))
{
for (k=;k<i;k++)
{
int x=A[j+k],y=A[j+k+i];
A[j+k]=x+y;
if (A[j+k]>=Mod) A[j+k]-=Mod;
A[j+k+i]=x-y+Mod;
if (A[j+k+i]>=Mod) A[j+k+i]-=Mod;
}
}
}
}
void UFWT(int *A,int len)
{int i,j,k;
for (i=;i<m;i<<=)
{
for (j=;j<m;j+=(i<<))
{
for (k=;k<i;k++)
{
int x=A[j+k],y=A[j+k+i];
A[j+k]=1ll*(x+y)*inv2%Mod;
A[j+k+i]=1ll*(x-y+Mod)*inv2%Mod;
}
}
}
}
void DP(int x,int y)
{int i;
for (i=;i<m;i++)
tmp[i]=a[x][i];
FWT(a[x],m);
FWT(a[y],m);
for (i=;i<m;i++)
a[x][i]=1ll*a[x][i]*a[y][i]%Mod;
UFWT(a[x],m);
for (i=;i<m;i++)
{
a[x][i]=a[x][i]+tmp[i];
if (a[x][i]>=Mod) a[x][i]-=Mod;
}
}
void dfs(int x,int pa)
{int i;
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if (v!=pa)
{
dfs(v,x);
DP(x,v);
}
}
for (i=;i<m;i++)
{
ans[i]=ans[i]+a[x][i];
if (ans[i]>=Mod) ans[i]-=Mod;
}
}
int main()
{int T,i,x,u,v,j;
cin>>T;
inv2=qpow(,Mod-);
while (T--)
{
memset(head,,sizeof(head));
num=;
memset(a,,sizeof(a));
memset(ans,,sizeof(ans));
scanf("%d%d",&n,&m);
for (i=;i<=n;i++)
{
x=gi();
a[i][x]=;
}
for (i=;i<=n-;i++)
{
u=gi();v=gi();
add(u,v);add(v,u);
}
dfs(,);
for (i=;i<m-;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[m-]);
}
}

HDU 5909 Tree Cutting的更多相关文章

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

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

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

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

  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(FWT+树形DP)

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

  5. hdu 5909 Tree Cutting —— 点分治

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

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

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

  7. HDU - 5909 Tree Cutting (树形dp+FWT优化)

    题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值.求一棵树中,连通子树值为[0,m)的个数. 分析: 设\(dp[i][j]\)为根为i,值为j的子树的个数. 则\(dp[i][j\o ...

  8. 【HDU 5909】 Tree Cutting (树形依赖型DP+点分治)

    Tree Cutting Problem Description Byteasar has a tree T with n vertices conveniently labeled with 1,2 ...

  9. HDU-6881 Tree Cutting (HDU多校D10T5 点分治)

    HDU-6881 Tree Cutting 题意 \(n\) 个点的一棵树,要求删除尽量少的点,使得删点之后还是一棵树,并且直径不超过 \(k\),求删除点的数量 分析 补题之前的一些错误想法: 尝试 ...

随机推荐

  1. Git简单图文教程

    环境: Windows [版本 10.0.15063]64位 Git-2.14.1 64位[下载] TortoiseGit-2.5.0.0 64位[下载],这是一个Git 客户端,外号"乌龟 ...

  2. Linux进程管理之task_struct结构体

    进程是处于执行期的程序以及它所管理的资源(如打开的文件.挂起的信号.进程状态.地址空间等等)的总称.注意,程序并不是进程,实际上两个或多个进程不仅有可能执行同一程序,而且还有可能共享地址空间等资源. ...

  3. bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图

    http://www.lydsy.com/JudgeOnline/problem.php?id=1023 dp[x] 表示以x为端点的最长链 子节点与x不在同一个环上,那就是两条最长半链长度 子节点与 ...

  4. PM2使用心得

    PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控.自动重启.负载均衡等,而且使用非常简单. 安装 npm install -g pm2 常用命令 $ npm i ...

  5. 数据结构与算法 —— 链表linked list(02)

    我们继续来看链表的第二道题,来自于leetcode: 两数相加 给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了 ...

  6. JAVA_SE基础——36.static的实际应用

    什么时候定义静态函数 如果功能内部没有访问到非静态数据(对象的特有数据.那么该功能就可以定义为静态) P.S. 静态方法作为类和接口的重要组成部分,可以通过类名或接口直接访问,通常将那些使用频率较高的 ...

  7. js控制表格实时编辑

    点击添加,在表格的最后一行添加一行表单元素,右侧按钮变为保存和取消.(点击保存,数据用ajax无刷新添加到界面,点击取消,取消此行的添加.)点击编辑,在本行改为表单,带有原来的值,右侧按钮变为确认和取 ...

  8. idea 找不到classpath 为resource下的xml

    注入时不能自动找到在src/main/resources下的xml. @ContextConfiguration(locations = { "classpath:applicationCo ...

  9. 安装 docker-compose

    安装Docker-Compose之前,请先安装 python-pip,安装好pip之后,就可以安装Docker-Compose了. 一.检查是否已经安装 二.安装 docker-compose 1.安 ...

  10. redis入门(04)redis的数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 1.String(字符串) ...