题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909

点分治,每次的 rt 是必选的点;

考虑必须选根的一个连通块,可以DP,决策就是在每个子树中决定选不选子树根,如果不选就跳过这个子树;

于是可以转化成 dfs 序上的DP;

每次重新标记一遍 dfs 序,但不改动 siz (也许可以改动但T了?),可能因为 siz 还和点分治的过程有关。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const xn=,inf=,mod=1e9+;
int n,m,v[xn],hd[xn],ct,to[xn<<],nxt[xn<<],siz[xn],dfn[xn],g[xn],tim;
int ans[xn],f[xn][xn],rt,mx,nt[xn];
bool vis[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
void upt(int &x,int y){x+=y; while(x>=mod)x-=mod; while(x<)x+=mod;}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void getrt(int x,int fa,int sum)
{
int nmx=; siz[x]=;
for(int i=hd[x],u;i;i=nxt[i])
{
if((u=to[i])==fa||vis[u])continue;
getrt(u,x,sum); siz[x]+=siz[u];
if(siz[u]>nmx)nmx=siz[u];
}
nmx=max(nmx,sum-siz[x]);
if(nmx<mx)mx=nmx,rt=x;
}
void dfs(int x,int fa)
{
dfn[x]=++tim; g[tim]=v[x];
for(int i=hd[x],u;i;i=nxt[i])
if((u=to[i])!=fa&&!vis[u])dfs(u,x);
nt[dfn[x]]=tim+;
}
void work(int x,int ss)
{
vis[x]=; tim=; dfs(x,);
for(int i=;i<=ss+;i++)memset(f[i],,sizeof f[i]);
f[][g[]]=;
for(int i=;i<=ss;i++)
for(int j=;j<m;j++)
if(f[i][j])upt(f[i+][j^g[i]],f[i][j]),upt(f[nt[i]][j],f[i][j]);
//printf("x=%d ss=%d\n",x,ss);
for(int j=;j<m;j++)upt(ans[j],f[ss+][j]);
//,printf("f[%d][%d]=%d\n",dfn[x]+siz[x],j,f[dfn[x]+siz[x]][j]);
for(int i=hd[x],u;i;i=nxt[i])
if(!vis[u=to[i]])
{
int ns=(siz[u]>siz[x]?ss-siz[x]:siz[u]);
mx=inf; getrt(u,,ns); work(rt,ns);
}
}
int main()
{
int T=rd();
while(T--)
{
n=rd(); m=rd();
for(int i=;i<=n;i++)v[i]=rd();
ct=; tim=;
for(int i=;i<=n;i++)hd[i]=;
for(int i=,x,y;i<n;i++)x=rd(),y=rd(),add(x,y),add(y,x);
for(int j=;j<m;j++)ans[j]=;
for(int i=;i<=n;i++)vis[i]=;
mx=inf; getrt(,,n); work(rt,n);
for(int j=;j<m;j++)printf("%d%c",ans[j],j==m-?'\n':' ');
}
return ;
}

hdu 5909 Tree Cutting —— 点分治的更多相关文章

  1. hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...

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

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

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

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

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

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

  5. HDU 5909 Tree Cutting(FWT+树形DP)

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

  6. HDU 5909 Tree Cutting

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

  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. vim对光标所在的数字进行增减

    真是vim会在不经意间给你惊喜...... 现在发现把光标移到某数字的上方,c-a是加1, c-x是减1 当时真有点众里寻他千百度的感觉

  2. 监控httpd的shell脚本

    #!/bin/bash # Apache httpd进程监控shell # 如果你在使用RHEL / CentOS / Fedora Linux,使用这个重启命令 RESTART="/sbi ...

  3. 2017-2018-1 20179209《Linux内核原理与分析》第十周作业

    设备与模块 设备分类 块设备 块设备可以以块为单位寻址,块大小随设备不同而不同:设备通常支持重定位操作,也就是对数据的随机访问.块设备的例子有外存,光盘等. 字符设备 字符设备不可寻址,仅供数据的流式 ...

  4. Java语言实现简单FTP软件------>连接管理模块的实现:主机与服务器之间的连接与关闭操作(八)

    (1)FTP连接 运行FTP客户端后,首先是连接FTP服务器,需要输入FTP服务器的IP地址及用户名.密码以及端口号后点击连接按钮开始连接FTP服务器,连接流程图如下图所示. 点击"连接&q ...

  5. tf.InteractiveSession()与tf.Session()

    tf.InteractiveSession():它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的.这对于工作在交互式环境中的人们来说非常便利,比如使用IPy ...

  6. Redis持久化——问题定位与优化(三)

    核心知识点: 1.fork操作 a.在RDB或AOF重写时,会执行fork操作创建子进程,fork操作是一个重量级操作. b.改善fork操作耗时的手段:避免使用Xen.配置Redis实例最大使用内存 ...

  7. 请简单介绍一下Spring

    Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. Spring ...

  8. 人生要golang

    第一篇 : 初识golang 第二篇 : 下载及安装 未完待续 ............................................

  9. 每天一个Linux命令(5)rm命令

    rm命令可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉.对于链接文件,只是删除整个链接文件,而原有文件保持不变. 注意:使用rm命令要格外小心.因为一旦 ...

  10. mysql 数据库使用

    1. 常用命令 2. 创建表 create table test ( test_id int, test_price decimal ); 或者 create table test2 as selec ...