裸的树上FWT
FWT取模很方便
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
char c;
inline void read(int&a)
{a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
#define ll long long
int n,m;
struct Chain
{
Chain*next;
int u;
}*Head[1001];
inline void Add(int u,int v)
{Chain*tp=new Chain;tp->next=Head[u];Head[u]=tp;tp->u=v;}
int Val[1001][1024];
int V[1001];
const
int Mod=(int)1e9+7,Rev=Mod+1>>1;
void FWT(int *a,int n,bool Div)
{
for(int i=0;(1<<i)<n;i++)
{
int t=1<<i;
for(int j=0;j<n;j++)
if(!(j&t))
{
int l=a[j],r=a[j|t];
if(Div)
a[j]=(l+r)*1ll*Rev%Mod,
a[j|t]=(l-r+Mod)*1ll*Rev%Mod;
else
a[j]=l+r,a[j|t]=l-r,
a[j]>=Mod?a[j]-=Mod:0,
a[j|t]<0?a[j+t]+=Mod:0;
}
}
}
void DFS(int u,int f)
{
FWT(Val[u],m,false);
for(Chain*tp=Head[u];tp;tp=tp->next)
if(f^tp->u)
{
DFS(tp->u,u);
FWT(Val[tp->u],m,0);
for(int i=0;i<m;i++)
Val[u][i]=Val[tp->u][i]*1ll*Val[u][i]%Mod;
FWT(Val[tp->u],m,1);
}
FWT(Val[u],m,1);
Val[u][0]++;
if(Val[u][0]==Mod)
Val[u][0]=0;
}
int main()
{
int T,a,b;
read(T);
while(T--)
{
memset(Head,0,sizeof(Head));
memset(Val,0,sizeof(Val));
read(n),read(m);
for(int i=1;i<=n;i++)
read(V[i]);
for(int i=1;i<n;i++)
read(a),read(b),Add(a,b),Add(b,a);
for(int i=1;i<=n;i++)
Val[i][V[i]]=1;
DFS(1,1);
ll C=0;
for(int j=1;j<=n;j++)
Val[j][0]--,Val[j][0]<0?Val[j][0]+=Mod:1;
for(int i=0;i<m;i++)
{
C=0;
for(int j=1;j<=n;j++)
C+=Val[j][i],C>=Mod?C-=Mod:C;
printf("%d%c",(C+Mod)%Mod,(i==m-1)?'\n':' ');
}
}
return 0;
}