题目链接: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. TypeScript环境安装,以及配置idea开发环境

    安装前准备 安装typescript需要用到npm管理工具,而npm是随同Node.js一起安装的包管理工具,所以要先安装Node 1.前往Node官网下载最新版安装包:http://nodejs.c ...

  2. 【MySQL】目录、文件权限问题

    详情如下: $ cat /usr/local/mysql/data/Phoenix-slow.log cat: /usr/local/mysql/data/Phoenix-slow.log: Perm ...

  3. 读写properties文件

    1. 读properties文件 Properties props = new Properties(); try { InputStream in = new FileInputStream(&qu ...

  4. 从源码看java线程状态

    关于java线程状态,网上查资料很混乱,有的说5种状态,有的说6种状态,初学者搞不清楚这个线程状态到底是怎么样的,今天我讲一下如何看源码去解决这个疑惑. 直接上代码: public class Thr ...

  5. 基于Spring框架应用的权限控制系统的研究和实现

    摘 要: Spring框架是一个优秀的多层J2EE系统框架,Spring本身没有提供对系统的安全性支持.Acegi是基于Spring IOC 和 AOP机制实现的一个安全框架.本文探讨了Acegi安全 ...

  6. 编码规范 | Java函数优雅之道(上)

    导读 随着软件项目代码的日积月累,系统维护成本变得越来越高,是所有软件团队面临的共同问题.持续地优化代码,提高代码的质量,是提升系统生命力的有效手段之一.软件系统思维有句话“Less coding, ...

  7. 对vue中nextTick()的理解及使用场景说明

    异步更新队列: 首先我们要对vue的数据更新有一定理解: vue是依靠数据驱动视图更新的,该更新的过程是异步的. 即:当侦听到你的数据发生变化时, Vue将开启一个队列(该队列被Vue官方称为异步更新 ...

  8. 【Kubernetes 系列四】Kubernetes 实战:管理 Hello World 集群

    目录 1. 创建集群 1.1. 安装 kubectl 1.1.1. 安装 kubectl 到 Linux 1.1.2. 安装 kubectl 到 macOS 1.1.3. 安装 kubectl 到 W ...

  9. win7-BIOS中开启AHCI模式电脑蓝屏怎么办?

    win7-BIOS中开启AHCI模式电脑蓝屏怎么办? 来源:U大师 u盘装系统 不少网友都表示给电脑安装win7系统后,如果在BIOS中开启IDE模式就一切正常而为AHCI模式时就会出现蓝屏.其实那是 ...

  10. 前端插件之Datatables使用--下篇

    工欲善其事,必先利其器 本系列文章介绍我在运维系统开发过程中用到的那些顺手的前端插件,上一篇文章介绍了Datatables插件的基本使用,这一篇文章作为上一篇的延续,会介绍Databases的一些高级 ...