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

点分治的话,每次要做一次树形DP;但时间应该是 siz*m2 的。可以用 FWT 变成 siz*mlogm ,但这里写的是把树变成序列来 DP 的方法,应该是 nlogn*m 的。

树上的一个点,如果选,就可以选它的孩子,所以它向它的第一个孩子连边;如果不选,就会跳到它的下一个兄弟或者是父亲的下一个兄弟之类的,向那边连一条边。

做出树的 dfs 序,把边都连在 dfs 序上;其实那个第一条边一定连向自己 dfs 序+1,即使自己没有孩子也是符合的,所以可以不用连了;第二条边可以通过传父亲的连边对象来解决。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=,mod=1e9+;
int T,n,m,w[N],hd[N],xnt,to[N<<],nxt[N<<],siz[N],rt,mn;
int dfn[N],tot,sta[N],top,f[N][M],g[N],nt[N],ans[M]; bool vis[N];
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
void upd(int &x){x>=mod?x-=mod:;}
void init()
{
xnt=;memset(hd,,sizeof hd);
memset(ans,,sizeof ans); memset(vis,,sizeof vis);
}
void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
void getrt(int cr,int fa,int s)
{
siz[cr]=; int mx=;
for(int i=hd[cr],v;i;i=nxt[i])
if(!vis[v=to[i]]&&v!=fa)
{
getrt(v,cr,s);siz[cr]+=siz[v];
mx=Mx(mx,siz[v]);
}
mx=Mx(mx,s-siz[cr]);if(mx<mn)mn=mx,rt=cr;
}
void dfs(int cr,int fa)
{
dfn[cr]=++tot;g[tot]=w[cr];
for(int i=hd[cr],v;i;i=nxt[i])
if(!vis[v=to[i]]&&v!=fa)dfs(v,cr);
}
void dfsx(int cr,int fa,int lst)
{
nt[dfn[cr]]=lst;
int l=top+;
for(int i=hd[cr],v;i;i=nxt[i])
if(!vis[v=to[i]]&&v!=fa)sta[++top]=v;
int r=top;
for(int i=hd[cr],v,p0=l;i;i=nxt[i])
if(!vis[v=to[i]]&&v!=fa)
{
dfsx(v,cr,p0==r?lst:dfn[sta[p0+]]);p0++;
}
}
void solve(int cr,int s)
{
vis[cr]=;
tot=;dfs(cr,);top=;dfsx(cr,,s+);
for(int i=;i<=s+;i++)memset(f[i],,sizeof f[i]);
f[][]=;
for(int i=;i<=s;i++)
for(int j=;j<m;j++)
{
if(!f[i][j])continue;
f[i+][j^g[i]]+=f[i][j];upd(f[i+][j^g[i]]);
f[nt[i]][j]+=f[i][j];upd(f[nt[i]][j]);
}
f[s+][]--;//dec the empty
for(int j=,k=s+;j<m;j++)ans[j]+=f[k][j],upd(ans[j]);
for(int i=hd[cr],v,ts;i;i=nxt[i])
if(!vis[v=to[i]])
{
ts=(siz[cr]>siz[v]?siz[v]:s-siz[cr]);
mn=N;getrt(v,cr,ts);solve(rt,ts);
}
}
int main()
{
T=rdn();
while(T--)
{
n=rdn();m=rdn();for(int i=;i<=n;i++)w[i]=rdn();
init();
for(int i=,u,v;i<n;i++)u=rdn(),v=rdn(),add(u,v),add(v,u);
mn=N;getrt(,,n);solve(rt,n);
for(int i=,j=m-;i<j;i++)printf("%d ",ans[i]);
printf("%d\n",ans[m-]);
}
return ;
}

hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)的更多相关文章

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

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

  2. hdu 5909 Tree Cutting —— 点分治

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

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

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

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

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

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

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

  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

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

  8. hdoj5909 Tree Cutting(点分治+树上dp转序列dp)

    题目链接:https://vjudge.net/problem/HDU-5909 题意:给一颗树,结点带权值v[i]<m.求异或和为k的子树个数(0<=k<m). 思路: 首先点分治 ...

  9. E. Alternating Tree 树点分治|树形DP

    题意:给你一颗树,然后这颗树有n*n条路径,a->b和b->a算是一条,然后路径的权值是 vi*(-1)^(i+1)  注意是点有权值. 从上头往下考虑是点分治,从下向上考虑就是树形DP, ...

随机推荐

  1. 【运维技术】windows安装apache服务器,实现域名对应端口的解析跳转

    linux 安装参考搭建dede项目的功能 windows 安装虚拟机的指南参考:http://jingyan.baidu.com/article/29697b912f6539ab20de3cf8.h ...

  2. Vue学习笔记之Vue的对象单体模式

    0x00 对象的单体模式 为了解决箭头函数this指向的问题 推出来一种写法 对象的单体模式 var person = { name:'小马哥', age:12, fav(){ console.log ...

  3. 20145335郝昊《网络攻防》Bof逆向基础——ShellCode注入与执行

    20145335郝昊<网络攻防>Bof逆向基础--ShellCode注入与执行 实验原理 关于ShellCode:ShellCode是一段代码,作为数据发送给受攻击服务器,是溢出程序和蠕虫 ...

  4. A TLS packet with unexpected length was received 解决方法

    参考:A TLS packet with unexpected length was received. 系统环境 主系统 OS X,虚拟机 Ubuntu 14.04 64bit. 问题描述 在git ...

  5. POJ 1034 The dog task(二分图匹配)

    http://poj.org/problem?id=1034 题意: 猎人和狗一起出去,狗的速度是猎人的两倍,给出猎人的路径坐标,除了这些坐标外,地图上还有一些有趣的点,而我们的狗,就是要尽量去多的有 ...

  6. eclipse中下载maven插件解决办法

    https://blog.csdn.net/qq_30546099/article/details/71195446 解决Eclipse Maven插件的最佳方案 https://www.cnblog ...

  7. XML_CPP_资料

    1.TinyXML解析xml文档 - zhoubl668的专栏:远帆,梦之帆! - 博客频道 - CSDN.NET.html http://blog.csdn.net/zhoubl668/articl ...

  8. Angular i18n

    Angular2中使用ngx-translate进行国际化http://blog.csdn.net/u014291497/article/details/61233033 在 Angular 项目中添 ...

  9. Getting 'The AWS Access Key Id you provided does not exist in our records' error with Amazon MWS

    I upgraded from one version of Amazon MWS (marketplace web service) version https://mws.amazonservic ...

  10. c++运算符优先级表

    优先级 操作符 描述 例子 结合性 1 () [] -> . :: ++ -- 调节优先级的括号操作符 数组下标访问操作符 通过指向对象的指针访问成员的操作符 通过对象本身访问成员的操作符 作用 ...