题目链接: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. Maven中央仓库发布历程

    一.前言 最近自己在学习Spring boot的过程中开发了一个组件 multithreadpool-spring-boot-starter,通过这个组件,我们可以动态根据配置文件进行多个线程池的初始 ...

  2. mysql新增一列为主键

    mysql新增一列为主键 由于一次疏忽在建表的时候忘记加上主键了, 但是目前来说表里面又有数据了,所以不能删表重建,所以需要新加一列主键 然后我就新加一列,并且为auto_increment,然后设置 ...

  3. Discuz论坛 自动加好友留言程序

    目录 [隐藏] 1 思路: 2 代码: 2.1 登录,获取Cookie: 2.2 获取FormHash: 2.3 发送加好友请求并留言: 思路: 一波未平一波又起, 拿到这个需求的时候对我来说还是有挑 ...

  4. Hibernate 框架

    首先,我们先来了解一下什么是 Hibernate 框架. 什么是 Hibernate 框架? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO ...

  5. RocketMq中网络通信之服务端

    一,Broker服务端入口(NettyServer端) 首先RocketMq网络通信采用的Netty通信.服务端主要集中在Broker中.我们先看一下Broker的启动类BrokerStartup 显 ...

  6. CSS3 Flex 布局教程

    网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂 ...

  7. android ——ListView

    谷歌官方文档的介绍:https://developer.android.com/reference/android/widget/ListView.html 显示可垂直滚动的视图集合,其中每个视图都立 ...

  8. MySQL-EXPLAIN执行计划字段解释

    做 MySQL 查询优化遇到明明建了索引查询仍然很慢,看这个 SQL 的执行计划,看它到底有没有用到索引,执行的具体情况.我们可以用 EXPLAIN 命令查看 SQL 的执行计划,SQL 优化的重要性 ...

  9. Ubuntu 16.04 安装 SVN-Client (RaabitVCS)

    1.添加源 sudo add-apt-repository ppa:rabbitvcs/ppa 2. 更新源 sudo apt-get update 3.安装依赖库 sudo apt-get inst ...

  10. python环境的安装 环境变量和系统变量

    一.python 的安装 python 2.7 和 python 3.6的安装(一路点点点就行) 在安装的时候注意一下红框的内容,意思代表将其添加到环境变量中 环境变量是在操作系统中一个具有特定名字的 ...