zoukankan      html  css  js  c++  java
  • HDU 5909 Tree Cutting

    传送门

    题意:

    有一棵n个点的无根树,节点依次编号为1到n,其中节点i的权值为vi,
    定义一棵树的价值为它所有点的权值的异或和。
    现在对于每个[0,m)的整数k,请统计有多少T的非空连通子树的价值等于k。

    Sample Input
    2
    4 4
    2 0 1 3
    1 2
    1 3
    1 4
    4 4
    0 1 3 1
    1 2
    1 3
    1 4
    Sample Output
    3 3 2 3
    2 4 2 3
    令f[i][j]表示以i为根的子树中异或和为j的联通块个数,v为i儿子
    f[i][j]+=f[i][k]*f[v][l]    (k^l==j)
    发现转移其实可以写成这种形式:
    $C_i=sum_{j^k=i}A_j*B_k$
    这和卷积有点类似,不过运算改成了异或
    这里就要用到FWT(快速沃尔什变换)
    就可以做到nlogn转移
    转移完后记得在加上原来的f[i][j],因为你可以不选v
    复杂度为$O(n^{2}logn)$
    卡常,少取模,不要定义long long变量
    这题还可以点分治
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 using namespace std;
      7 struct Node
      8 {
      9   int next,to;
     10 }edge[2501];
     11 int num,head[1501],Mod=1e9+7,inv2,tmp[2001],a[1001][2001],ans[2001],n,m;
     12 int gi()
     13 {
     14   char ch=getchar();
     15   int x=0;
     16   while (ch<'0'||ch>'9') ch=getchar();
     17   while (ch>='0'&&ch<='9')
     18     {
     19       x=x*10+ch-'0';
     20       ch=getchar();
     21     }
     22   return x;
     23 }
     24 void add(int u,int v)
     25 {
     26   num++;
     27   edge[num].next=head[u];
     28   head[u]=num;
     29   edge[num].to=v;
     30 }
     31 int qpow(int x,int y)
     32 {
     33   int res=1;
     34   while (y)
     35     {
     36       if (y&1) res=1ll*res*x%Mod;
     37       x=1ll*x*x%Mod;
     38       y/=2;
     39     }
     40   return res;
     41 }
     42 void FWT(int *A,int len)
     43 {int i,j,k;
     44   for (i=1;i<m;i<<=1)
     45     {
     46       for (j=0;j<m;j+=(i<<1))
     47     {
     48       for (k=0;k<i;k++)
     49         {
     50           int x=A[j+k],y=A[j+k+i];
     51           A[j+k]=x+y;
     52           if (A[j+k]>=Mod) A[j+k]-=Mod;
     53           A[j+k+i]=x-y+Mod;
     54           if (A[j+k+i]>=Mod) A[j+k+i]-=Mod;
     55         }
     56     }
     57     }
     58 }
     59 void UFWT(int *A,int len)
     60 {int i,j,k;
     61     for (i=1;i<m;i<<=1)
     62     {
     63       for (j=0;j<m;j+=(i<<1))
     64     {
     65       for (k=0;k<i;k++)
     66         {
     67           int x=A[j+k],y=A[j+k+i];
     68           A[j+k]=1ll*(x+y)*inv2%Mod;
     69           A[j+k+i]=1ll*(x-y+Mod)*inv2%Mod;
     70         }
     71     }
     72     }
     73 }
     74 void DP(int x,int y)
     75 {int i;
     76   for (i=0;i<m;i++)
     77     tmp[i]=a[x][i];
     78   FWT(a[x],m);
     79   FWT(a[y],m);
     80   for (i=0;i<m;i++)
     81     a[x][i]=1ll*a[x][i]*a[y][i]%Mod;
     82   UFWT(a[x],m);
     83   for (i=0;i<m;i++)
     84     {
     85       a[x][i]=a[x][i]+tmp[i];
     86       if (a[x][i]>=Mod) a[x][i]-=Mod;
     87     }
     88 }
     89 void dfs(int x,int pa)
     90 {int i;
     91   for (i=head[x];i;i=edge[i].next)
     92     {
     93       int v=edge[i].to;
     94       if (v!=pa)
     95     {
     96       dfs(v,x);
     97       DP(x,v);
     98     }
     99     }
    100   for (i=0;i<m;i++)
    101     {
    102       ans[i]=ans[i]+a[x][i];
    103       if (ans[i]>=Mod) ans[i]-=Mod;
    104     }
    105 }
    106 int main()
    107 {int T,i,x,u,v,j;
    108   cin>>T;
    109   inv2=qpow(2,Mod-2);
    110   while (T--)
    111     {
    112       memset(head,0,sizeof(head));
    113       num=0;
    114       memset(a,0,sizeof(a));
    115       memset(ans,0,sizeof(ans));
    116       scanf("%d%d",&n,&m);
    117       for (i=1;i<=n;i++)
    118     {
    119       x=gi();
    120       a[i][x]=1;
    121     }
    122       for (i=1;i<=n-1;i++)
    123     {
    124       u=gi();v=gi();
    125       add(u,v);add(v,u);
    126     }
    127       dfs(1,0);
    128       for (i=0;i<m-1;i++)
    129       printf("%d ",ans[i]);
    130       printf("%d
    ",ans[m-1]);
    131     }
    132 }
  • 相关阅读:
    helloc
    传Intel镁光合资公司重启新加坡闪存芯片厂投产计划 月产能可达10万片
    关于c++ cout输出顺序问题。
    记录一次迁移Apollo Server V3的过程
    从springfox迁移到springdoc
    angular和spring boot的standalone部署
    随便总结几条委托和事件的知识点
    TCP连接的建立与断开
    开博第一天
    使用HTTP协议时判断客户端是否“在线”?
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8430651.html
Copyright © 2011-2022 走看看