标签:between -- span lov style 路径 contain drive change
题目链接:
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 210 Accepted Submission(s): 75
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=5e4+5;
int n,k,fk,a[maxn],p[13];
int siz[maxn],son[maxn],vis[maxn],root,MAX,cnt,num[1030],d[maxn],cn=0,head[maxn];
LL ans=0;
struct Edge
{
int to,next;
}edge[2*maxn];
inline void add_edge(int from,int to)
{
edge[cn].to=to;
edge[cn].next=head[from];
head[from]=cn++;
}
inline void init()
{
cn=0;
fk=(1<<k)-1;
ans=0;
for(int i=0;i<=n;i++)vis[i]=0;
memset(head,-1,sizeof(head));
}
void get_siz(int cur,int fa)
{
siz[cur]=1;
son[cur]=0;
for(int i=head[cur];i!=-1;i=edge[i].next)
{
int x=edge[i].to;
if(x==fa||vis[x])continue;
get_siz(x,cur);
siz[cur]+=siz[x];
if(siz[x]>son[cur])son[cur]=siz[x];
}
}
void find_root(int cur,int fa,int rt)
{
if(siz[rt]-siz[cur]>son[cur])son[cur]=siz[rt]-siz[cur];
if(son[cur]<MAX)MAX=son[cur],root=cur;
for(int i=head[cur];i!=-1;i=edge[i].next)
{
int x=edge[i].to;
if(x==fa||vis[x])continue;
find_root(x,cur,rt);
}
}
void get_state(int cur,int fa,int sta)
{
d[cnt++]=sta;
num[sta]++;
for(int i=head[cur];i!=-1;i=edge[i].next)
{
int x=edge[i].to;
if(vis[x]||x==fa)continue;
get_state(x,cur,a[x]|sta);
}
}
LL cal(int cur,int sta)
{
cnt=0;
memset(num,0,sizeof(num));
get_state(cur,0,sta);
for(int i=0;i<k;i++)
{
for(int j=fk;j>=0;j--)
{
if(!(p[i]&j))num[j]+=num[j|p[i]];
}
}
LL ret=0;
for(int i=0;i<cnt;i++)ret=ret+num[fk^d[i]];
return ret;
}
void dfs(int cur)
{
MAX=n;
get_siz(cur,0);
find_root(cur,0,cur);
int Root=root;
ans=ans+cal(root,a[Root]);
vis[root]=1;
for(int j=head[Root];j!=-1;j=edge[j].next)
{
int x=edge[j].to;
if(vis[x])continue;
ans=ans-cal(x,(a[x]|a[Root]));
dfs(x);
}
}
int main()
{
p[0]=1;for(int i=1;i<=11;i++)p[i]=p[i-1]*2;
while(scanf("%d%d",&n,&k)!=EOF)
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]=p[a[i]-1];
}
int u,v;
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(1);
printf("%lld\n",ans);
}
return 0;
}
标签:between -- span lov style 路径 contain drive change
原文地址:http://www.cnblogs.com/zhangchengc919/p/6042601.html