题目链接

\(Description\)

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

\(n\leq 1000,m\leq 2^{10}\)。

\(Solution\)

在每个连通块的根节点处统计。\(f[x][k]\)表示以\(x\)为根,异或和为\(k\)的连通块(子树)有多少个。

那么\(f[x][k]=f[x][k]+\sum_{i\ \mathbb{xor}\ j=k}f[x][i]*f[v][j],\ v=son[x]\)。

后一部分就是异或卷积,可以用\(FWT\)优化。

具体实现,不需要每次转移一棵子树都\(FWT,IFWT\)一次。中间过程一直用\(FWT\)后的\(f\)计算就可以了。

可能有的问题是,\(f\)本身(\(f[x][k]\))还要加上自己,必须在转移的时候\(IFWT\)回去?不妨在\(f[v]\)计算完之后\(IFWT(f[v])\),令\(f[v][0]++\),然后再\(FWT\)回去,用这个\(f[v]\)去更新\(f[x]\)。这样就可以直接用\(FWT\)后的\(f\)计算了。

\(f[x][0]\)在计算前是不能\(+1\)的,因为必须要求\(f[x]\)代表的非空连通块是以\(x\)为根的。

最后把所有\(f[i]\ IFWT\)回去,再令\(f[i][0]\)--。

复杂度\(O(nm\log m)\)。

所以有这两种写法的差异。。

https://www.cnblogs.com/cjyyb/p/9065611.html

https://blog.csdn.net/clover_hxy/article/details/72722352

还可以点分治。。在第二篇里有。不想写了。

//858MS 5528K(怎么那么多跑的很快的啊--点分?)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define inv2 500000004
#define mod 1000000007
#define Add(x,y) (x+y>=mod?x+y-mod:x+y)
#define Sub(x,y) (x<y?x-y+mod:x-y)
typedef long long LL;
const int N=1024+5; int lim,Enum,H[N],nxt[N<<1],to[N<<1],f[1005][N];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void FWT(int *a,int lim,int opt)
{
for(int i=2; i<=lim; i<<=1)
for(int j=0,mid=i>>1; j<lim; j+=i)
for(int k=j; k<j+mid; ++k)
{
int x=a[k], y=a[k+mid];
a[k]=Add(x,y), a[k+mid]=Sub(x,y);
if(opt==-1) a[k]=1ll*a[k]*inv2%mod, a[k+mid]=1ll*a[k+mid]*inv2%mod;
}
}
void DFS(int x,int fa)
{
FWT(f[x],lim,1);
for(int i=H[x],v; i; i=nxt[i])
if((v=to[i])!=fa)
{
DFS(v,x);
for(int j=0; j<lim; ++j) f[x][j]=1ll*f[x][j]*f[v][j]%mod;
}
FWT(f[x],lim,-1), f[x][0]=Add(f[x][0],1), FWT(f[x],lim,1);
} int main()
{
static LL Ans[N];
for(int T=read(); T--; )
{
Enum=0, memset(H,0,sizeof H);
memset(f,0,sizeof f), memset(Ans,0,sizeof Ans);
int n=read(),m=read(); lim=m;
for(int i=1; i<=n; ++i) ++f[i][read()];
for(int i=1; i<n; ++i) AE(read(),read());
DFS(1,1);
for(int i=1; i<=n; ++i)
{
FWT(f[i],lim,-1), f[i][0]=Sub(f[i][0],1);
for(int j=0; j<m; ++j) Ans[j]+=f[i][j];
}
for(int i=0; i<m; ++i) printf("%d%c",int(Ans[i]%mod)," \n"[i+1==m]);//输出格式。。
}
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优化)

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

  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. POJ 2378.Tree Cutting 树形dp 树的重心

    Tree Cutting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4834   Accepted: 2958 Desc ...

  6. [poj3107/poj2378]Godfather/Tree Cutting树形dp

    题意:求树的重心(删除该点后子树最大的最小) 解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次dp求每个子树的节点个数,第二次dp求解答案即可. 此题一开始一直T,后 ...

  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. python学习:绝对路径和相对路径

    python学习:绝对路径和相对路径 大牛们应该对路径都很了解了,这篇文章主要给像我这样的入门小白普及常识用的,啊哈 下面的路径介绍针对windows,其他平台的暂时不是很了解. 在编写的py文件中打 ...

  2. 如何用enable_shared_from_this 来得到指向自身的shared_ptr 及对enable_shared_from_this 的理解

    在看<Linux多线程服务端编程:使用muduo C++网络库> 的时候,在说到如何防止在将对象的 this 指针作为返回值返回给了调用者时可能会造成的 core dump.需使用 ena ...

  3. saltStack运维工具的部署及master迁移实现的过程详解

    服务器端:192.168.3.87 客户端:192.168.3.86.192.168.3.108 1.salt服务器端安装 192.168.3.87 rpm -Uvh http://mirrors.y ...

  4. centos6下通用二进制安装mysql5.5.33

    mysql5.5通用二进制格式安装方法 1.解压到 /usr/local 目录 # tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local 2 ...

  5. 利用navcat为mysql数据库单独的表赋权限及表结构同步

    为mysql数据库单独的表赋权限 场景:考勤系统需要拿OA数据库td_oa中的flow_run和flow_run_data表中的数据做考勤计算 考勤系统只需要读取这两张表的数据,所以只需要开通一个单独 ...

  6. 转载:2.2.2 配置项的语法格式《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19627.html 从上文的示例可以看出,最基本的配置项语法格式如下: 配置项名 配置项值1 配置项值2 - ; 下面解释一下配置项的 ...

  7. dispatchers 设置

    Oracle连接方式(dispatchers 设置) oracle 响应客户端请求有两种方式: 1 专有连接:用一个服务器进程响应一个客户端请求 2 共享连接:用一个分派器(dispatcher)响应 ...

  8. Oracle 相关概念

    注:本文来源于 <腾科OCP培训课堂>.非准许商业活动. 标题:Oracle  相关概念 --->数据库名.实例名.数据库域名.全局数据名.服务名 一:数据库名 1:什么是数据库名 ...

  9. Socket 实现聊天功能

    注:本文来自:简书:jianshu 作者:jijs链接:http://www.jianshu.com/p/7c0722a8b66f來源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  10. My Sql控制台命令

    1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...