分析:
FWT优化DP板子。
直接把N^2的转移换成NlogN即可,其余不变。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 1030
#define MOD 1000000007
using namespace std;
typedef long long ll;
ll tr[MAXN][MAXN];
void FWT(ll A[],int N){
for(int d=1;d<N;d<<=1)for(int m=d<<1,i=0;i<N;i+=m)for(int j=0;j<d;j++){
ll x=A[i+j],y=A[i+j+d];A[i+j]=(x+y)%MOD;A[i+j+d]=(x-y+MOD)%MOD;}
}
const ll inv2=500000004ll;
void IFWT(ll A[],int N){
for(int d=1;d<N;d<<=1)for(int m=d<<1,i=0;i<N;i+=m)for(int j=0;j<d;j++){
ll x=A[i+j],y=A[i+j+d];A[i+j]=(x+y)*inv2%MOD;A[i+j+d]=(x-y+MOD)*inv2%MOD;}
}
int t,n,m;
vector<int> a[MAXN];
int val[MAXN];
void dfs(int x,int fa=0){
memset(tr[x],0,sizeof tr[x]);tr[x][val[x]]++;FWT(tr[x],m);for(int i=0;i<int(a[x].size());i++){
int u=a[x][i];if(u==fa) continue;dfs(u,x);FWT(tr[u],m);for(int i=0;i<m;i++)tr[x][i]=(tr[x][i]*tr[u][i])%MOD;IFWT(tr[u],m);}IFWT(tr[x],m);tr[x][0]++;
}
ll ans[MAXN];
int main(){
SF("%d",&t);int u,v;while(t--){
SF("%d%d",&n,&m);for(int i=1;i<=n;i++){
SF("%d",&val[i]);a[i].clear();}for(int i=1;i<n;i++){
SF("%d%d",&u,&v);a[u].push_back(v);a[v].push_back(u); }dfs(1);memset(ans,0,sizeof ans);for(int i=1;i<=n;i++)for(int j=0;j<m;j++)ans[j]=(ans[j]+tr[i][j])%MOD;ans[0]-=n;for(int i=0;i<m;i++){
PF("%lld",ans[i]);if(i!=m-1)PF(" ");}PF("\n");}
}