题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5977

题解:这题一看就知道是状压dp然后看了一下很像是点分治(有点明显)然后就是简单的点分治+状压dp,这里只要稍微改一下模版就行了。还有注意一下这里的cau状态枚举然后就没什么了

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int M = 5e4 + ;
struct Edge {
int v , next;
}edge[M << ];
int head[M] , e , Size , root , n , k , a[M] , ssr;
ll ans;
bool vis[M];
void init() {
memset(head , - , sizeof(head));
memset(vis , false , sizeof(vis));
ans = ;
e = ;
ssr = (( << k) - );
}
void add(int u , int v) {
edge[e].v = v;
edge[e].next = head[u];
head[u] = e++;
}
int size[M] , mx[M];
ll Hash[];
void dfs_size(int u , int pre) {
size[u] = ;
mx[u] = ;
for(int i = head[u] ; i != - ; i = edge[i].next) {
int v = edge[i].v;
if(v == pre || vis[v]) continue;
dfs_size(v , u);
size[u] += size[v];
mx[u] = max(mx[u] , size[v]);
}
}
void dfs_root(int r , int u , int pre) {
mx[u] = max(mx[u] , size[r] - size[u]);
if(mx[u] < Size) Size = mx[u] , root = u;
for(int i = head[u] ; i != - ; i = edge[i].next) {
int v = edge[i].v;
if(v == pre || vis[v]) continue;
dfs_root(r , v , u);
}
}
void get_root(int u , int pre) {
dfs_size(u , pre);
dfs_root(u , u , pre);
}
int num , State[M];
void find_state(int u , int pre , int state) {
State[num++] = state;
for(int i = head[u] ; i != - ; i = edge[i].next) {
int v = edge[i].v;
if(vis[v] || v == pre) continue;
find_state(v , u , state | ( << a[v]));
}
}
ll cau(int u , int state) {
num = ;
find_state(u , - , state);
memset(Hash , , sizeof(Hash));
ll sum = ;
for(int i = ; i < num ; i++) Hash[State[i]]++;
for(int i = ; i < num ; i++) {
Hash[State[i]]--;
sum += Hash[ssr];//这里由于是枚举时0枚举不到所以先加上ssr^0.
for (int s0 = State[i]; s0; s0 = (s0 - ) & State[i])
sum += Hash[(( << k) - ) ^ s0];
Hash[State[i]]++;
}
return sum;
}
void dfs(int u) {
Size = n;
get_root(u , -);
ans += cau(root , ( << a[root]));
vis[root] = true;
int rt = root;
for(int i = head[root] ; ~i ; i = edge[i].next) {
int v = edge[i].v;
if(vis[v]) continue;
ans -= cau(v , ( << a[rt]) | ( << a[v]));
dfs(v);
}
}
int main() {
while(scanf("%d%d" , &n , &k) != EOF) {
init();
for(int i = ; i <= n ; i++) scanf("%d" , &a[i]) , a[i]--;
for(int i = ; i < n - ; i++) {
int u , v;
scanf("%d%d" , &u , &v);
add(u , v);
add(v , u);
}
if (k == ) {
printf("%lld\n", (ll)n * (ll)n);
continue;
}
dfs();
printf("%lld\n" , ans);
}
return ;
}

hdu 5977 Garden of Eden(点分治+状压)的更多相关文章

  1. HDU 5977 Garden of Eden(点分治求点对路径颜色数为K)

    Problem Description When God made the first man, he put him on a beautiful garden, the Garden of Ede ...

  2. HDU 5977 Garden of Eden (树分治+状态压缩)

    题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点? 析:对于路径,就是两类,第一种情况,就是跨过根结点,第二种是不跨过根结点,分别讨论就好 ...

  3. HDU 6984 - Tree Planting(数据分治+状压 dp)

    题面传送门 傻逼卡常屑题/bs/bs,大概现场过得人比较少的原因就是它比较卡常罢(Fog 首先对于这样的题我们很难直接维护,不过注意到这个 \(n=300\) 给得很灵性,\(k\) 比较小和 \(k ...

  4. HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)

    CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...

  5. HDU 5977 Garden of Eden

    题解: 路径统计比较容易想到点分治和dp dp的话是f[i][j]表示以i为根,取了i,颜色数状态为j的方案数 但是转移这里如果暴力转移就是$(2^k)^2$了 于是用FWT优化集合或 另外http: ...

  6. HDU - 5977 Garden of Eden (树形dp+容斥)

    题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...

  7. HDU-5977 - Garden of Eden 点分治

    HDU - 5977 题意: 给定一颗树,问树上有多少节点对,节点对间包括了所有K种苹果. 思路: 点分治,对于每个节点记录从根节点到这个节点包含的所有情况,类似状压,因为K<=10.然后处理每 ...

  8. hdu-5977 Garden of Eden(树分治)

    题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  9. HDU 3920Clear All of Them I(状压DP)

    HDU 3920   Clear All of Them I 题目是说有2n个敌人,现在可以发n枚炮弹,每枚炮弹可以(可以且仅可以)打两个敌人,每一枚炮弹的花费等于它所行进的距离,现在要消灭所有的敌人 ...

随机推荐

  1. HTML5 第二章 列表和表格和媒体元素

    列表: (1)什么是列表? 列表就是信息资源的一种展示形式. (2)无序列表: 语法: <ul> <li>第1项</li> <li>第2项</li ...

  2. 【原创】JAVA进程突然消失的原因?

    引言 值此七夕佳节,烟哥放弃了无数妹纸的邀约,坐在电脑面前码字,就是为了给读者带来新的知识,这是一件伟大的事业! 好吧,实际情况是没人约.为了化解尴尬,我决定卖力写文章,嗯,一定是我过于屌丝! 好了, ...

  3. Java学习多线程第一天

    内容介绍 Thread 线程创建 线程池 线程状态图 1 多线程 1.1     多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序 ...

  4. java支付宝app支付-代码实现

    1.我们需要在支付宝商户平台配置好,取到四个参数如下(这是支付宝官方配置地址):https://www.cnblogs.com/fuzongle/p/10217144.html 合作身份者ID:123 ...

  5. http客户端-性能比较系列-第一篇-单线程

    系列文章: 单线程性能测试:https://www.cnblogs.com/victor2302/p/11077208.html 多线程性能测试:https://www.cnblogs.com/vic ...

  6. PowerShell安装IIS

    Windows作web开发的同学,应该都会用到IIS服务器.比如在阿里云或是Azure上购买一台新的服务器,默认是没有安装IIS的(安装的镜像就带有IIS或是MySql的除外).届时需要安装IIS,安 ...

  7. POI通用导出Excel数据(包括样式设计)

    前言 前一段时间我写过通用的导入Excel,前几天也写了导出pdf格式的,还有我之前搞得导出Word,我在之前的博客也都介绍了导出和导入是一个道理,无非是一个获取一个是赋值.昨天有一位同仁看了我的Ex ...

  8. Flink 源码解析 —— 深度解析 Flink 序列化机制

    Flink 序列化机制 https://t.zsxq.com/JaQfeMf 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭 ...

  9. c# 多进程写信息到前台控件

    private void DispMsg(string strMsg, bool clearlb = false) { if (this.lberror.InvokeRequired == false ...

  10. Gitment评论插件的使用

    前言 继上一篇的 GitPages部署自己的网站 现在开始添加博客的评论插件Gitment.这里的话我是使用hexo添加gitment插件,如果不是使用hexo,请到官网指定这里. 开始 第一步 注册 ...