zoukankan      html  css  js  c++  java
  • BZOJ3696 化合物

    我们可以树形dp...

    令f[p][d]表示以p为根的子树,与p距离为d的结点数

    然后我们计算答案:

    一种是从某个节点q到根p的方案,对和为d的贡献是1

    另一种是p的一个子树中的节点x到另一个子树中的节点y的方案,对和为d[x] ^ d[y]的贡献为1

    第二种我们可以通过f暴力求出,话说什么时候去研究一下FWT啊。。。

     1 /**************************************************************
     2     Problem: 3696
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:476 ms
     7     Memory:207460 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12  
    13 using namespace std;
    14 const int N = 1e5 + 5;
    15 const int H = 525;
    16  
    17 struct edge {
    18     int next, to;
    19     edge() {}
    20     edge(int _n, int _t) : next(_n), to(_t) {}
    21 } e[N];
    22  
    23 int n;
    24 int first[N], tot;
    25 int f[N][H], ans[H], dep[N];
    26  
    27 inline int read() {
    28     int x = 0, sgn = 1;
    29     char ch = getchar();
    30     while (ch < '0' || '9' < ch) {
    31         if (ch == '-') sgn = -1;
    32         ch = getchar();
    33     }
    34     while ('0' <= ch && ch <= '9') {
    35         x = x * 10 + ch - '0';
    36         ch = getchar();
    37     }
    38     return sgn * x;
    39 }
    40  
    41 inline void Add_Edge(int x, int y) {
    42     e[++tot] = edge(first[x], y), first[x] = tot;
    43 }
    44  
    45 #define y e[x].to
    46 void dfs(int p) {
    47     int x, i, j;
    48     f[p][0] = 1;
    49     for (x = first[p]; x; x = e[x].next) {
    50         dfs(y);
    51         for (i = 0; i <= dep[p]; ++i)
    52             for (j = 0; j <= dep[y]; ++j)
    53                 ans[i ^ (j + 1)] += f[p][i] * f[y][j];
    54         dep[p] = max(dep[p], dep[y] + 1);
    55         for (i = 0; i <= dep[y]; ++i)
    56             f[p][i + 1] += f[y][i];
    57     }
    58 }
    59 #undef y
    60  
    61 int main() {
    62     int i, mx;
    63     n = read();
    64     for (i = 2; i <= n; ++i)
    65         Add_Edge(read(), i);
    66     dfs(1);
    67     for (mx = H - 1; mx; --mx)
    68         if (ans[mx]) break;
    69     for (i = 0; i <= mx; ++i)
    70         printf("%d
    ", ans[i]);
    71     return 0;
    72 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    Docker和k8s的区别与介绍
    NFS网络文件系统详解
    NFS文件系统及搭建NFS共享服务
    Tomcat 端口配置,及原理详解
    svn使用教程
    buff/cache内存占用过多
    关于xcode:如何在Objective-C中使用符号断点获取参数
    iOS开发消除编译警告
    建模的能力才是一个人和核心能力
    android sutdio 环境搭建
  • 原文地址:https://www.cnblogs.com/rausen/p/4352046.html
Copyright © 2011-2022 走看看