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. AtCoder Regular Contest 099 C~E

    C - Minimization 枚举就可以了 因为最后一定会变成1,所以第一次操作的区间就包含1会比较优,然后枚举1在第一次操作区间里排第几个取min即可 #include<iostream& ...

  2. bzoj 1673: [Usaco2005 Dec]Scales 天平【dfs】

    真是神奇 根据斐波那契数列,这个a[i]<=c的最大的i<=45,所以直接搜索即可 #include<iostream> #include<cstdio> usin ...

  3. composer windows安装,使用新手入门[转]

    原:https://blog.csdn.net/csdn_dengfan/article/details/54912039 一.前期准备: 1.下载安装包,https://getcomposer.or ...

  4. SpringMVC实现Action的两种方式以及与Struts2的区别

    4.程序员写的Action可采用哪两种方式? 第一.实现Controller接口第二.继承自AbstractCommandController接口 5.springmvc与struts2的区别? 第一 ...

  5. poj3411 Paid Roads

    思路: 搜索.注意点和边都有可能经过多次. 实现: #include <iostream> #include <cstdio> #include <vector> ...

  6. 【工具】Github

    项目目录结构设计与git远程仓库的建立 git码云仓库建立:在码云网站上新建组织和项目. 配置sshkey认证和公钥:命令行ssh-keygen -t rsa -C "xxxxx@xxxxx ...

  7. LR接口测试---Java Vuser之jdbc查询(调试前)

    在eclipse下编写好的代码: import lrapi.lr; import java.sql.Connection; import java.sql.DriverManager; import ...

  8. 最容易理解的HMM文章

    wiki上一个比较好的HMM例子 分类 隐马尔科夫模型 HMM(隐马尔科夫模型)是自然语言处理中的一个基本模型,用途比较广泛,如汉语分词.词性标注及语音识别等,在NLP中占有很重要的地位.网上关于HM ...

  9. (转)Hibernate框架基础——一对多关联关系映射

    http://blog.csdn.net/yerenyuan_pku/article/details/52746413 上一篇文章Hibernate框架基础——映射集合属性详细讲解的是值类型的集合(即 ...

  10. 让ios支持http协议

    ios默认只支持https协议,打开info.plist文件,加入以下设置 NSAppTransportSecurity NSAllowsArbitraryLoads