zoukankan      html  css  js  c++  java
  • 【CQOI2017】老C的键盘

    Description

      https://loj.ac/problem/3023
      一句话题意:给你一棵完全二叉树,每条边有一个方向,求这棵树有多少种不同的拓扑序。

    Solution

      简化题意后,其实就是一个普及组树形 DP。
      设 (dp(i,j)) 表示以点 (i) 为根的子树中,(i) 号点排第 (j) 名的方案数。
      利用 (j) 这个辅助维,我们可以枚举点 (i) 的排名 (k),扫一遍点 (i) 的所有儿子,每次会新来一个以 (v) 为根的子树合并到以 (i) 为根的子树上,枚举点 (i) 和点 (v) 在各自子树中的排名(记为 (rank_i)(rank_v)),若题目限制点 (i) 排在点 (v) 前面,则枚举要满足 (rank_i+rank_vle k),否则题目限制点 (i) 排在点 (v) 后面,则枚举要满足 (rank_i+rank_vgt k)
      设从 ([1,k-1]) 中选 (rank_i-1) 个整数的方案数为 (L),从 ([k+1,size_i+size_v]) 中选 (size_i-rank_i) 个整数的方案数为 (R),则 (dp(i,k) += dp(i,rank_i) imes dp(v,rank_v) imes L imes R)。这很好理解。
      最后算时间复杂度,还是那个套路,看起来是 (O(n^4)),其实还是 (O(n^3)),因为最里面两层循环的最大上界分别为 (size_i)(size_v),这等价于在两棵子树内选 (2) 个点。那么这就是个以前讲过的套路,树上每对点只会在 LCA 处被枚举一次,故最里面两层循环套 dfs 的时间是 (O(n^2)),乘上一个枚举 (k) 的循环,总时间 (O(n^3))

      code

  • 相关阅读:
    pyinstaller模块
    使用reduce方法数组去重
    Linux的关机与重启命令
    splice和slice的区别
    发现splice的新大陆
    text-decoration和outline
    前端中关于堆和栈的那些事
    git
    前端代码规范
    弹性布局在项目中的使用示例
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/loj3023.html
Copyright © 2011-2022 走看看