【HDU5909】Tree Cutting(FWT)

【HDU5909】Tree Cutting(FWT)

题面

vjudge
题目大意:
给你一棵\(n\)个节点的树,每个节点都有一个小于\(m\)的权值
定义一棵子树的权值为所有节点的异或和,问权值为\(0..m-1\)的所有子树的个数

题解

考虑\(dp\)
设\(f[i][j]\)表示以\(i\)为根节点的子树中,异或和为\(j\)的子树的个数
很显然,每次合并就是两个\(dp\)值做\(xor\)卷积
那么直接用\(FWT\)优化就行了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 1111
#define MOD (1000000007)
#define inv2 (500000004)
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int n,m,N;
void FWT(int *P,int opt)
{
    for(int i=2;i<=N;i<<=1)
        for(int p=i>>1,j=0;j<N;j+=i)
            for(int k=j;k<j+p;++k)
            {
                int x=P[k],y=P[k+p];
                P[k]=(x+y)%MOD;P[k+p]=(x-y+MOD)%MOD;
                if(opt==-1)P[k]=1ll*P[k]*inv2%MOD,P[k+p]=1ll*P[k+p]*inv2%MOD;
            }
}
int f[MAX][1<<10],ans[MAX];
void dfs(int u,int ff)
{
    FWT(f[u],1);
    for(int i=h[u];i;i=e[i].next)
    {
        int v=e[i].v;if(v==ff)continue;
        dfs(v,u);
        for(int j=0;j<N;++j)f[u][j]=1ll*f[u][j]*f[v][j]%MOD;
    }
    FWT(f[u],-1);f[u][0]=(f[u][0]+1)%MOD;FWT(f[u],1);
}
int main()
{
    int T=read();
    while(T--)
    {
        n=read();m=read();cnt=1;N=m;
        memset(f,0,sizeof(f));memset(h,0,sizeof(h));memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;++i)f[i][read()]++;
        for(int i=1;i<n;++i)
        {
            int u=read(),v=read();
            Add(u,v);Add(v,u);
        }
        dfs(1,0);
        for(int i=1;i<=n;++i)FWT(f[i],-1);
        for(int i=1;i<=n;++i)f[i][0]=(f[i][0]-1+MOD)%MOD;
        for(int i=1;i<=n;++i)
            for(int j=0;j<m;++j)
                ans[j]=(ans[j]+f[i][j])%MOD;
        for(int i=0;i<m;++i,(i==m)?putchar('\n'):putchar(' '))printf("%d",ans[i]);
    }
}

原文地址:https://www.cnblogs.com/cjyyb/p/9065611.html

时间: 2024-08-25 15:41:46

【HDU5909】Tree Cutting(FWT)的相关文章

【CF662C】Binary Table(FWT)

[CF662C]Binary Table(FWT) 题面 洛谷 CF 翻译: 有一个\(n*m\)的表格(\(n<=20,m<=10^5\)), 每个表格里面有一个\(0/1\), 每次可以将一行或者一列的\(01\)全部翻转 回答表格中最少有多少个\(1\) 题解 发现\(n\)很小,\(m\)很大 状压是跑不掉了 如果我们确定翻转哪些行,那么答案唯一确定(贪心的选每一列中\(0/1\)的较小值) 相同的列显然可以合并, 把每一列按照\(01\)状压,记\(a[i]\)为状态为\(i\)的列

Android自定义组件系列【5】——进阶实践(1)

简介 项目开发中发现问题.解决问题这个过程中会出现很多问题,比如重复出现.某个问题的遗留,这些问题的本质就是设计模式.今天记录设计模式的知识点. 内容 在java以及其他的面向对象设计模式中,类与类之间主要有6种关系,他们分别是:依赖.关联.聚合.组合.继承.实现.它们的耦合度依次增强. 依赖关系:对于两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系.关联关系:分为单向关联和双向关联.在java中,单向关联表现为:类A当中使用了

【Chrome】Chrome插件开发(一)插件的简单实现

不同浏览器插件开发比较 Chrome的插件开发起来最简单,总体上看没什么新的技术,开发语言就是javascript,web前端工程师能很快上手. Firefox的插件开发则复杂许多,涉及到环境的搭建和一些WEB以外的技术. IE的插件开发就更复杂了,需要熟悉C++和COM技术,当然还要装微软的Visual Studio. 这里有篇老外写的文章,对比Chrome.Opera和Firefox的插件开发的:http://blog.nparashuram.com/2011/10/writing-brow

【TYVJ】1307 联络员(最小生成树)

http://tyvj.cn/Problem_Show.aspx?id=1307 kruskal裸题.(水题红色警报) #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> using namespace std; #define rep(i, n) for(int

【转】引导界面(五)实现应用程序只启动一次引导界面

这篇文章算是对整个引导界面开发专题的一个终结了吧,个人觉得大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了,要是在今后的开发中遇到了更好玩,更有趣的引导界面,博主也会在这里及时的跟大家分享,今天的内容主要是教大家的应用程序只有在第一次启动的时候显示引导界面,以后在启动程序的时候就不再显示了. 其实要想实现这样的效果,只要使用SharedPreferences类,就会让程序变的非常简单,下面来详细介绍一下这个类的使用方法 一.SharedPreferences的详

【转】Robust regression(稳健回归)

Robust regression(稳健回归) 语法 b=robustfit(X,y) b=robustfit(X,y,wfun,tune) b=robustfit(X,y,wfun,tune,const) [b,stats]=robustfit(...) 描述 b=robustfit(X,y) 通过执行稳健回归来估计线性模型y=Xb,并返回一个由回归系数组成的向量b.X是一个n*p预测变量矩阵,y是一个n*1观测向量.计算使用的方法是加 上bisquare加权函数的迭代重加权最小二乘法.默认的

【转载】PHP的(&lt;&lt;&lt;EOT)在PHP中添加html

在W3school上学PHP,看到第一句就是"PHP 文件可包含文本.HTML 标签以及脚本"在后来的学习别人的代码,发现在需要HTML代码的PHP脚本中,多用这么几种方法第一种是在HTML中加PHP.大段大段的html代码中,在各个需要执行php的地方.这种方法在ASP的程序中比较常见.例子:     <head>    <meta http-equiv="Content-Type" content="text/html; charse

Android自定义组件系列【6】——进阶实践(3)

上一篇<Android自定义组件系列[5]--进阶实践(2)>继续对任老师的<可下拉的PinnedHeaderExpandableListView的实现>进行了分析,这一篇计划中间插一段"知识点",对Android中的事件分发机制进行解析.细心的朋友可能会发现,打开大牛写的Android项目,里面很多组件都是自定义的(这就是为什么界面和体验这么吸引你的原因),但是要灵活的去自定义组件就必须对手势(也就是各种监听)必须熟悉,能处理好事件之间的关系. 先看一段代码:

Android自定义组件系列【7】——进阶实践(4)

上一篇<>中补充了关于Android中事件分发的过程知识,这一篇我们接着来分析任老师的<可下拉的PinnedHeaderExpandableListView的实现>. 一.StickyLayout中的OnGiveUpTouchEventListener接口的作用是什么? public interface OnGiveUpTouchEventListener { public boolean giveUpTouchEvent(MotionEvent event); } 在Sticky