Garden of Eden

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description
When God made the first man, he put him on a beautiful
garden, the Garden of Eden. Here Adam lived with all animals. God gave Adam
eternal life. But Adam was lonely in the garden, so God made Eve. When Adam was
asleep one night, God took a rib from him and made Eve beside him. God said to
them, “here in the Garden, you can do everything, but you cannot eat apples from
the tree of knowledge.”
One day, Satan came to the garden. He changed into a
snake and went to live in the tree of knowledge. When Eve came near the tree
someday, the snake called her. He gave her an apple and persuaded her to eat it.
Eve took a bite, and then she took the apple to Adam. And Adam ate it, too.
Finally, they were driven out by God and began a hard journey of life.
The
above is the story we are familiar with. But we imagine that Satan love
knowledge more than doing bad things. In Garden of Eden, the tree of knowledge
has n apples, and there are k varieties of apples on the tree. Satan wants to
eat all kinds of apple to gets all kinds of knowledge.So he chooses a starting
point in the tree,and starts walking along the edges of tree,and finally stops
at a point in the tree(starting point and end point may be same).The same point
can only be passed once.He wants to know how many different kinds of schemes he
can choose to eat all kinds of apple. Two schemes are different when their
starting points are different or ending points are different.
 
Input
There are several cases.Process till end of
input.
For each case, the first line contains two integers n and k, denoting
the number of apples on the tree and number of kinds of apple on the tree
respectively.
The second line contains n integers meaning the type of the
i-th apple. Types are represented by integers between 1 and k .
Each of the
following n-1 lines contains two integers u and v,meaning there is one edge
between u and v.1≤n≤50000, 1≤k≤10
 
Output
For each case output your answer on a single
line.
 
Sample Input
3 2
1 2 2
1 2
1 3
 
Sample Output
6
分析:考虑树分治;
   那么对于当前根,我们dfs得到一个位或集合;
   那么我们要求位或值全1的点对数;
   那么枚举其中一个点a后,我们要知道b的数目,c[a]|c[b]=(1<<m)-1,c[a]表示从当前根到a的位或值;
   不难发现这是高维前缀和;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <cassert>
#include <ctime>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define inf 0x3f3f3f3f
#define mod 998244353
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
#define ls (rt<<1)
#define rs (rt<<1|1)
#define all(x) x.begin(),x.end()
const int maxn=1e5+;
const int N=4e5+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qmul(ll p,ll q,ll mo){ll f=;while(q){if(q&)f=(f+p)%mo;p=(p+p)%mo;q>>=;}return f;}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p%mod;p=p*p%mod;q>>=;}return f;}
int n,m,k,t,c[maxn],p[maxn],son[maxn],sz,root,bit[<<],q[maxn],tmp[<<];
ll ans;
bool vis[maxn];
vi e[maxn];
void getroot(int x,int y)
{
int i;
son[x]=;p[x]=;
rep(i,,e[x].size()-)
{
int z=e[x][i];
if(z==y||vis[z])continue;
getroot(z,x);
son[x]+=son[z];
p[x]=max(p[x],son[z]);
}
p[x]=max(p[x],sz-son[x]);
if(p[x]<p[root])root=x;
}
void getbit(int x,int y)
{
q[x]|=(<<c[x]);
bit[q[x]]++;
int i;
rep(i,,e[x].size()-)
{
int z=e[x][i];
if(z==y||vis[z])continue;
q[z]=q[x];
getbit(z,x);
}
}
ll cal(int x,int &p)//计算集合中位或为(1<<m)-1的对数;
{
memset(bit,,sizeof(bit));
getbit(x,);
memcpy(tmp,bit,sizeof(bit));
int i,j;
rep(i,,m-)
{
rep(j,,(<<m)-)
{
if(j>>i&)continue;
tmp[j]+=tmp[j^(<<i)];
}
}
ll ret=;
rep(i,,(<<m)-)ret+=(ll)bit[i]*tmp[i^((<<m)-)];
return ret;
}
void gao(int x)
{
int i;
q[x]=;
ans+=cal(x,q[x]);
vis[x]=true;
rep(i,,e[x].size()-)
{
int y=e[x][i];
if(!vis[y])
{
q[y]=(<<c[x]);
ans-=cal(y,q[y]);
p[]=sz=son[y];
getroot(y,root=);
gao(root);
}
}
}
int main(){
int i,j;
while(~scanf("%d%d",&n,&m))
{
ans=;
rep(i,,n)
{
scanf("%d",&c[i]);
c[i]--;
e[i].clear();
vis[i]=false;
}
rep(i,,n-)
{
int x,y;
scanf("%d%d",&x,&y);
e[x].pb(y);e[y].pb(x);
}
p[]=sz=n;
getroot(,root=);
gao(root);
printf("%lld\n",ans);
}
return ;
}

Garden of Eden的更多相关文章

  1. HDU5977 Garden of Eden(树的点分治)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5977 Description When God made the first man, he ...

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

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

  3. uva10001 Garden of Eden

    Cellular automata are mathematical idealizations of physical systems in which both space and time ar ...

  4. 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 ...

  5. hdu5977 Garden of Eden

    都不好意思写题解了 跑了4000多ms 纪念下自己A的第二题 (我还有一道freetour II wa20多发没A...呜呜呜 #include<bits/stdc++.h> using ...

  6. HDU 5977 Garden of Eden

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

  7. HDU5977 Garden of Eden 【FMT】【树形DP】

    题目大意:求有所有颜色的路径数. 题目分析:参考codeforces997C,先利用基的FMT的性质在$O(2^k)$做FMT,再利用只还原一位的特点在$O(2^k)$还原,不知道为什么网上都要点分治 ...

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

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

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

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

随机推荐

  1. 10.27night清北刷题班

    /* 枚举每个部分的总和,利用前缀和进行检验. 如果能分成4部分就一定能分成2部分,就筛了一边素数优化.清空数组!!! */ #include<bits/stdc++.h> #define ...

  2. npm install 安装软件,出现 operation not permitted, mkdir 'C:\Program Files\nodejs\node_cache'

    问题如下图: 解决办法: 在开始菜单栏里打开cmd的时,右击选择“以管理员身份运行”.然后再在打开的cmd里运动install就没问题了. 这个问题应该是当时安装依赖时,我们是以管理员身份运行的:所以 ...

  3. BACnet开发资料与调试工具

    一.开发资料 1.认识BACnet协议 2.BACnet网络讲义: 链接:https://pan.baidu.com/s/1A6OOUxvJe1zIYbockqTEsQ提取码:wz49 二.调试工具 ...

  4. 类似QQ消息左滑删除的Demo

    最近在网上学到一篇类似QQ消息左滑删除的demo,完善了下代码,感觉还不错,特此分享一波: CustomSwipeListView.java 是个继承自ListView的类,里面调用了自定义View ...

  5. 【hdu多校联考第二场】Odd Shops

    Description 这道题的题意是这道难读,大概就是给你n个商店,每个商店的重量为i的商品用ai表示,对于任意商店的a数列都是相同的,重量的范围为[1,10] 求购买方案总数为奇数的重量一共有多少 ...

  6. G - And Then There Was One (约瑟夫环变形)

    Description Let’s play a stone removing game. Initially, n stones are arranged on a circle and numbe ...

  7. Redis基础---5个基本数据结构(比较性记忆)

    “ Redis是一个内存数据库,只用硬盘来进行持久化. Mongodb是半内存数据库 Mysql是硬盘数据库 ” 1. Redis启动 安装好了之后.运行redis-3.2.8/src/下的redis ...

  8. js解析地址栏参数

    /** * 获取地址栏中url后面拼接的参数 * eg: * 浏览器地址栏中的地址:http://1.1.1.1/test.html?owner=2db08226-e2fa-426c-91a1-66e ...

  9. sp_Msforeachtable与sp_Msforeachdb详解

      一.简要介绍: 系统存储过程sp_MSforeachtable和sp_MSforeachdb,是微软提供的两个不公开的存储过程.从mssql6.5开始,存放在SQL Server的MASTER数据 ...

  10. 对Oracle 、SQL Server、MySQL、PostgreSQL数据库优缺点分析

    对Oracle .SQL Server.MySQL.PostgreSQL数据库优缺点分析 Oracle Database Oracle Database,又名Oracle RDBMS,或简称Oracl ...