当前位置: 代码迷 >> 综合 >> 【FWT】HDU5909 Tree Cutting
  详细解决方案

【FWT】HDU5909 Tree Cutting

热度:19   发布时间:2023-09-27 04:48:46.0

分析:

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");}
}
  相关解决方案