题目大意

给定一颗树,每个点有点权,问对于每个m,有多少个联通块的权值异或和为m。

题解

解法1:可以考虑树形dp,设dp[u][i]表示以u为根的子树中u必须选,联通块权值异或值为i的联通块个数。

转移是m^2的,用FWT优化为mlogm,总复杂度nmlogm

解法2:考虑加一个限制:给一个根,根必须选。

我们可以考虑在欧拉序上做文章,考虑到一个欧拉序的位置上,下一位置是它的儿子,如果我们选择了儿子节点,就往下一个位置转移,否则就跨过这颗子树,转移到下一次回溯到这个点的位置。

这个过程可以用dfs实现。

然后考虑选定点的过程,可以用点分治优化,复杂度nmlogn。

从运行常数来看,点分治的常数小一些。

代码(FWT)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1009
using namespace std;
typedef long long ll;
const int mod=1e9+;
int dp[N][<<],ans[<<],head[N],tot,n,m,a[N],inv,tag[<<],T;
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline int power(int x,int y){
int ans=;
while(y){
if(y&)ans=1ll*ans*x%mod;x=1ll*x*x%mod;y>>=;
}
return ans;
}
struct edge{int n,to;}e[N<<];
inline void add(int u,int v){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;}
inline void FWT(int *b,int tag){
// cout<<"(";
for(int i=;i<m;i<<=)
for(int j=;j<m;j+=(i<<))
for(int k=;k<i;++k){
int x=b[j+k],y=b[i+j+k];
b[j+k]=(x+y)%mod;b[i+j+k]=(x-y+mod)%mod;
if(tag)b[j+k]=1ll*b[j+k]*inv%mod,b[i+j+k]=1ll*b[i+j+k]*inv%mod;
}
// cout<<")";
}
void dfs(int u,int fa){
dp[u][a[u]]=;
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa){
int v=e[i].to;
dfs(v,u);
for(int j=;j<m;++j)tag[j]=dp[u][j];
FWT(tag,);FWT(dp[v],);
for(int j=;j<m;++j)tag[j]=1ll*tag[j]*dp[v][j]%mod;
FWT(tag,);
for(int j=;j<m;++j)(dp[u][j]+=tag[j])%=mod;
}
for(int j=;j<m;++j)(ans[j]+=dp[u][j])%=mod;
}
inline void unit(){
memset(ans,,sizeof(ans));
memset(dp,,sizeof(dp));
memset(head,,sizeof(head));
tot=;
}
signed main(){
T=rd();inv=power(,mod-);
while(T--){
n=rd();m=rd();int u,v;unit();
for(int i=;i<=n;++i)a[i]=rd();
for(int i=;i<n;++i){
u=rd();v=rd();add(u,v);add(v,u);
}
dfs(,);
for(int j=;j<m-;++j)printf("%d ",ans[j]);printf("%d\n",ans[m-]);
}
return ;
}

代码(点分治)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1009
using namespace std;
int size[N],tot,head[N],d[N],a[N],sum,m,n,root,dp[N][<<],ans[<<],T;
bool vis[N];
const int mod=1e9+;
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
struct edge{
int n,to;
}e[N<<];
inline void add(int u,int v){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;}
void getroot(int u,int fa){
d[u]=;size[u]=;
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa&&!vis[e[i].to]){
int v=e[i].to;getroot(v,u);
size[u]+=size[v];d[u]=max(d[u],size[v]);
}
d[u]=max(d[u],sum-size[u]);
if(d[u]<d[root])root=u;
}
void getsize(int u,int fa){
size[u]=;
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa&&!vis[e[i].to]){
int v=e[i].to;getsize(v,u);size[u]+=size[v];
}
}
inline void MOD(int &x){while(x>=mod)x-=mod;}
void calc(int u,int fa){
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa&&!vis[e[i].to]){
int v=e[i].to;
for(int j=;j<m;++j)MOD(dp[v][j^a[v]]+=dp[u][j]);
calc(v,u);
for(int j=;j<m;++j)MOD(dp[u][j]+=dp[v][j]),dp[v][j]=;
}
}
void solve(int u){
vis[u]=;
dp[u][a[u]]=;calc(u,);
for(int i=;i<m;++i)MOD(ans[i]+=dp[u][i]),dp[u][i]=;
for(int i=head[u];i;i=e[i].n)if(!vis[e[i].to]){
int v=e[i].to;
root=n+;sum=size[v];
getroot(v,u);getsize(root,);
solve(root);
}
}
inline void unit(){
memset(vis,,sizeof(vis));
memset(head,,sizeof(head));tot=;
}
int main(){
// freopen("in","r",stdin);
// freopen("out","w",stdout);
T=rd();
while(T--){
n=rd();m=rd();unit();int u,v;
for(int i=;i<=n;++i)a[i]=rd();
for(int i=;i<n;++i){u=rd();v=rd();add(u,v);add(v,u);}
root=n+;d[root]=n;sum=n;
getroot(,);getsize(root,);
solve(root);
for(int i=;i<m-;++i)printf("%d ",ans[i]),ans[i]=;
printf("%d\n",ans[m-]);ans[m-]=;
}
return ;
}

HDU5909Tree Cutting的更多相关文章

  1. hdu5909-Tree Cutting(树形dp)

    偷偷抄bestcoser上面hnust_zhaozhixuan的代码 = = 因为题解看不懂阿 #include <cstdio> #include <cstring> typ ...

  2. hdu5909-Tree Cutting【FWT】

    正题 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5909 题目大意 给出\(n\)和\(m\)(\(m=2^k\)).再给出一个大小为\(n\)的树 ...

  3. [ACM_几何] Metal Cutting(POJ1514)半平面割与全排暴力切割方案

    Description In order to build a ship to travel to Eindhoven, The Netherlands, various sheet metal pa ...

  4. 贪心 Codeforces Round #300 A Cutting Banner

    题目传送门 /* 贪心水题:首先,最少的个数为n最大的一位数字mx,因为需要用1累加得到mx, 接下来mx次循环,若是0,输出0:若是1,输出1,s[j]--: 注意:之前的0的要忽略 */ #inc ...

  5. 水题 Codeforces Round #300 A Cutting Banner

    题目传送门 /* 水题:一开始看错题意,以为是任意切割,DFS来做:结果只是在中间切出一段来 判断是否余下的是 "CODEFORCES" :) */ #include <cs ...

  6. POJ 2311 Cutting Game(Nim博弈-sg函数/记忆化搜索)

    Cutting Game 题意: 有一张被分成 w*h 的格子的长方形纸张,两人轮流沿着格子的边界水平或垂直切割,将纸张分割成两部分.切割了n次之后就得到了n+1张纸,每次都可以选择切得的某一张纸再进 ...

  7. UVa 10003 (可用四边形不等式优化) Cutting Sticks

    题意: 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用. 分析: d(i, j)表示切割第i个切点到第j个切点这段所需的最小费用.则有d(i, j) = ...

  8. Cutting Sticks

    题意: l长的木棒,给出n个切割点,每切一次的费用为切得木棒的长度,完成切割的最小费用. 分析: 区间dp入门,区间dp的特点,一个大区间的解可以转换成小区间的解组合起来,每个切割点的标号代表边界. ...

  9. Hadoop之父Doug Cutting

    生活中,可能所有人都间接用过他的作品,他是Lucene.Nutch .Hadoop等项目的发起人.是他,把高深莫测的搜索技术形成产品,贡献给普罗大众:还是他,打造了目前在云计算和大数据领域里如日中天的 ...

随机推荐

  1. Nginx Configuring HTTPS servers

    Configuring HTTPS servershttp://nginx.org/en/docs/http/configuring_https_servers.html Configuring HT ...

  2. Python技术之书籍汇总

    近日,一直在学习Python,发现有关的书籍还是很多值得一读的,所以在此总结一下.以后慢慢去研读吧!!! Python入门 <Python编程快速上手——让繁琐工作自动化> 作者: [美] ...

  3. PHP之CLI模式

    转载: http://www.cnblogs.com/zcy_soft/archive/2011/12/10/2283437.html 所有的PHP发行版,不论是编译自源代码的版本还是预创建的版本,都 ...

  4. Cannot connect to database because the database client

    问题描述: arcgis server10.1  arcgis sde10出现下面问题 Cannot connect to  database because the database client ...

  5. 配置SQLServer,允许远程连接

    需要别人远程你的数据库,首先需要的是在一个局域网内,或者连接的是同一个路由器,接下来就是具体步骤: (一)首先是要检查SQLServer数据库服务器中是否允许远程链接.其具体操作为: (1)打开数据库 ...

  6. [转帖]利用hydra(九头蛇)暴力破解内网windows登录密码

    利用hydra(九头蛇)暴力破解内网windows登录密码 https://blog.csdn.net/weixin_37361758/article/details/77939070 尝试了下 能够 ...

  7. Day 4-7 -configparser模块

    此模块用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser. 常用方法: import configparser conf = configpar ...

  8. C# Note17: 使用Ionic.Zip.dll实现解压缩文件

    首先下载ionic.Zip.dll,然后在项目中添加该引用,之后就可以在cs中使用了: using Ionic.Zip; #region Ionic.Zip压缩文件 private readonly ...

  9. prometheus和metrucs-server (k8s监控)

    资源指标:metrucs-server 自定义指标:prometheus, k8s-prometheus-adapter(转换prometheus数据的格式) 新一代架构: 核心指标流水线:由kube ...

  10. 使用synchronized 实现ReentrantLock(美团面试题目)

    刚看到这个题目的时候无从下手,因为觉得synchronized和lock在加锁的方式上有很大不同,比如,看看正常情况下synchronized时如何加锁的. 方式一: public synchroni ...