zoukankan      html  css  js  c++  java
  • Codeforces 955F Heaps

    题目传送门

      传送点I

      传送点II

      传送点III

    题目大意

      给定一棵以1为根的树,定义$dp_{k}(u)$表示在$u$的子树内存在的深度最大的满k叉树的深度,求$sum_{u = 1}^{n}sum_{k = 1}^{n}dp_{k}(u)$。

      以某个点$x$为根存在一棵深度$m$的满$k$叉树是指,它满足下面任意一条:

    1. $m = 1$。
    2. 当$m eq 1$时,$x$存在$k$个子节点,分别以它们为根存在一棵深度为$m - 1$的满$k$叉树。

      先讲讲我的挂掉的做法。

      因为是满$k$叉树,所以$dp_{k}(u)leqslant log_{k}n, k > 1$,由此推出当$k geqslant sqrt{n}$时,$dp_{k}(u) leqslant 2$。

      所以有了以下做法:

    • 当$1leqslant k < sqrt{n}$时,我们进行$O(n)$的动态规划。设$f_{u}$表示以点$u$为根,存在的深度最大的满$k$叉树的深度。转移取子节点中第$k$大的$f$值在加1,不存在就是1。当然这里找$k$大要用 nth_element 。
    • 当$k geqslant sqrt{n}$时,直接通过度数计算。

      看起来$O(nsqrt{n})$非常地优秀,题解也说

      然而实际上:

      因为$dp_{k}(u) leqslant log_{k}n$,所以当$k > 1$的时候$dp_{k} leqslant log_{2}n$。然后反转值和下标,考虑什么时候取每个值。

      我们同样注意到$dp_{k}$的某些不严格单调的性质。

    • 如果$u$是$v$的父节点,那么$dp_{k}(u) geqslant dp_{k}(v)$
    • 若$aleqslant b$,则$dp_{a}(u) geqslant dp_{b}(u)$。

      设$h_{k, i}$表示以$i$为根存在的最深的满$k$叉树的深度。

      如果某个$h$值被增大,那么我就沿着它的父节点向上跳去更新$dp$值,直到某个点已经不能更新。这样能够保证这一部分时间复杂度是$O(nlog n)$。

      因为要将值增大,那就从大到小考虑每个$k$。

      同时我们设$f_{i, j}$表示使得$h_{k}(i) geqslant j$ 成立的最大的$j$。

      转移很简单,我们找最大的$k$,使得子节点中第$k$大的$f_{s, j - 1}geqslant k$。这个可以排个序然后直接扫。

      然后用刚刚的方法更新$Delta answer$,然后就做完了。

      总时间复杂度$O(nlog_{2}^{2} n)$。

    Code

     1 /**
     2  * Codeforces
     3  * Problem#955F
     4  * Accepted
     5  * Time: 327ms
     6  * Memory: 66900k
     7  */
     8 #include <bits/stdc++.h>
     9 #ifndef WIN32
    10 #define Auto "%lld"
    11 #else
    12 #define Auto "%I64d"
    13 #endif
    14 using namespace std;
    15 typedef bool boolean;
    16 #define ll long long
    17 #define pii pair<int, int>
    18 #define fi first
    19 #define sc second
    20 
    21 const int N = 3e5 + 5, bzmax = 20;
    22 
    23 int n;
    24 int h[N];
    25 int f[N][bzmax];
    26 int buf[N], par[N];
    27 vector<pii> upd[N];
    28 vector<int> g[N];
    29 ll res;
    30 int dres;
    31 
    32 inline void init() {
    33     scanf("%d", &n);
    34     for (int i = 1, u, v; i < n; i++) {
    35         scanf("%d%d", &u, &v);
    36         g[u].push_back(v);
    37         g[v].push_back(u);
    38     }
    39 }
    40 
    41 int dp(int p, int fa) {
    42     int rt = 0;
    43     par[p] = fa;
    44 
    45     for (int i = 0; i < (signed) g[p].size(); i++) {
    46         int e = g[p][i];
    47         if (e ^ fa)
    48             rt = max(rt, dp(e, p));
    49     }
    50 
    51     f[p][1] = n;
    52     for (int t = 2; t < bzmax; t++) {
    53         int tp = 0;
    54         for (int i = 0; i < (signed) g[p].size(); i++) {
    55             int e = g[p][i];
    56             if ((e ^ fa) && f[e][t - 1])
    57                 buf[++tp] = f[e][t - 1];
    58         }
    59         
    60         sort(buf + 1, buf + tp + 1, greater<int>());
    61 
    62         for (int i = tp; i && !f[p][t]; i--)
    63             if (buf[i] >= i)
    64                 f[p][t] = i;
    65         if (f[p][t] > 1)
    66             upd[f[p][t]].push_back(pii(p, t));
    67     }
    68 
    69     res += rt + 1;
    70     return rt + 1;
    71 }
    72 
    73 void update(int p, int v) {
    74     while (p) {
    75         if (v <= h[p])
    76             break;
    77         dres += v - h[p];
    78         h[p] = v, p = par[p];
    79     }
    80 }
    81 
    82 inline void solve() {
    83     dp(1, 0);
    84     dres = n;
    85     for (int i = 1; i <= n; i++)
    86         h[i] = 1;
    87     for (int k = n; k > 1; k--) {
    88         for (int i = 0; i < (signed) upd[k].size(); i++)
    89             update(upd[k][i].fi, upd[k][i].sc);
    90         res += dres;
    91     }
    92     printf(Auto, res);
    93 }
    94 
    95 int main() {
    96     init();
    97     solve();
    98     return 0;
    99 }
  • 相关阅读:
    CSS3 2D转换
    CSS3 选择器
    CSS3 counters计数器学习笔记
    Web 部署 Server IP可以访问,Server Name 访问出错
    Windows server 2012 +IIS 8.0 Web 部署后在服务器端可以打开网页,在局域网其他电脑中打不开
    关于EF调用存储过程那点事...
    从一个路口转向另一个路口需要多少步
    PCA的数学原理(非常值得阅读)!!!!其实更重要的应该是实际意义
    BMP文件输入输出
    说明
  • 原文地址:https://www.cnblogs.com/yyf0309/p/9693586.html
Copyright © 2011-2022 走看看