zoukankan      html  css  js  c++  java
  • hdu 5909 Tree Cutting FWT

    显然的树状DP,dp[u][i]表示以u为根的子树中,价值为i的子树的数量。

    转移也很显然。开始时,dp[u][val[u]]为1。每次多一个子树v,就是dp[u]' = dp[u] + ∑dp[u]*dp[v](卷积)。使用FWT处理即可。复杂度O(N*M*logM)

     1 #include <cstdio>
     2 using namespace std;
     3 typedef long long ll;
     4 const int MAXN = 1100,MAXM = 2100,mo = 1000000007;
     5 int head[MAXN],v[MAXN],to[MAXM],nxt[MAXM],res[1024],dp[MAXN][1024];
     6 int n,m,T,cnt,inv2;
     7 int fpow(int x,int k)
     8 {
     9     if (k == 1)
    10         return x;
    11     int t = fpow(x,k >> 1);
    12     if (k & 1)
    13         return (ll)t * t % mo * x % mo;
    14     return (ll)t * t % mo;
    15 }
    16 void add(int x,int y)
    17 {
    18     nxt[++cnt] = head[x];
    19     to[cnt] = y;
    20     head[x] = cnt;
    21 }
    22 void fwt(int *a,int len,bool inv)
    23 {
    24     for(int d = 1;d < len;d <<= 1)
    25     {
    26         for(int h = d << 1,i = 0;i <= len - 1;i += h)
    27             for(int j = 0;j < d;j++)
    28             {
    29                 int x = a[i + j],y = a[i + j + d];
    30                 a[i + j] = (x + y) % mo;
    31                 a[i + j + d]=(x - y + mo) % mo;
    32             }
    33         if (inv == true)    
    34             for (int i = 0;i <= len - 1;i++)
    35                 a[i] = (ll)a[i] * inv2 % mo;
    36     }
    37 }
    38 void dfs(int x,int frm)
    39 {
    40     int tmp1[1024],tmp2[1024];
    41     dp[x][v[x]] = 1;
    42     for (int i = head[x];i;i = nxt[i])
    43     {
    44         if (to[i] == frm)
    45             continue;
    46         dfs(to[i],x);
    47         for (int o = 0;o <= m - 1;o++)
    48         {
    49             tmp1[o] = dp[x][o]; 
    50             tmp2[o] = dp[to[i]][o];
    51         }
    52         fwt(tmp1,m,false);
    53         fwt(tmp2,m,false);
    54         for (int o = 0;o <= m - 1;o++)
    55             tmp1[o] = (ll)tmp1[o] * tmp2[o] % mo;
    56         fwt(tmp1,m,true);
    57         for (int o = 0;o <= m - 1;o++)
    58             dp[x][o] = (dp[x][o] + tmp1[o]) % mo;
    59     }
    60 }
    61 int main()
    62 {
    63     inv2 = fpow(2,mo - 2);
    64     for (scanf("%d",&T);T != 0;T--)
    65     {
    66         cnt = 0;
    67         scanf("%d%d",&n,&m);
    68         for (int i = 1;i <= n;i++)
    69             scanf("%d",&v[i]);
    70         int tx,ty;
    71         for (int i = 1;i <= n - 1;i++)
    72         {
    73             scanf("%d%d",&tx,&ty);
    74             add(tx,ty);
    75             add(ty,tx); 
    76         }
    77         dfs(1,0);
    78         for (int i = 1;i <= n;i++)
    79             for (int j = 0;j <= m - 1;j++)
    80                 res[j] = (res[j] + dp[i][j]) % mo;
    81         for (int i = 0;i <= m - 2;i++)
    82             printf("%d ",res[i]);
    83         printf("%d
    ",res[m - 1]); 
    84         for (int i = 1;i <= cnt;i++)
    85             nxt[i] = 0;
    86         for (int i = 1;i <= n;i++)
    87             head[i] = 0;
    88         cnt = 0;
    89         for (int i = 1;i <= n;i++)
    90             for (int j = 0;j <= m - 1;j++)
    91                 dp[i][j] = 0;
    92         for (int i = 0;i <= m - 1;i++)
    93             res[i] = 0;
    94     }
    95     return 0;
    96 }
    心之所动 且就随缘去吧
  • 相关阅读:
    Angular1.0
    当今流行的 React.js 适用于怎样的 Web App?
    bower的权限问题
    淡定啊淡定
    JBoss for luna
    JQuery的二维码插件
    今天学人家玩云主机
    laravel5.2/laravel5.3入门指南 Windows 上快速安装并运行 Laravel 5.x
    验证mySqli扩展是否
    Amazon EC2 的名词解释
  • 原文地址:https://www.cnblogs.com/iat14/p/11362609.html
Copyright © 2011-2022 走看看