HDU5909 Tree Cutting

裸的樹上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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章