首页 > 其他分享 >Solution - Atcoder ARC157E XXYX Binary Tree

Solution - Atcoder ARC157E XXYX Binary Tree

时间:2024-10-02 17:00:31浏览次数:1  
标签:Atcoder XXYX int 个数 texttt Tree 叶子 maxn 节点

考虑这个不存在 \(\texttt{YY}\) 的限制,与 \(\texttt{XX}\) 个数为变量的限制相比较,看起来 \(\texttt{Y}\) 就更特殊,于是考虑从 \(\texttt{Y}\) 的视角来分析问题。

同时考虑到因为有 \(A + B + C = n - 1\),所以 \(\texttt{XX}\) 其实也不是很重要,因为只需要让 \(\texttt{XY}\) 和 \(\texttt{YX}\) 的个数满足条件就可以了。

注:这之后的分析默认遵守无 \(\texttt{YY}\),即不存在自己与父亲皆为 \(\texttt{Y}\) 的情况。

于是可以考虑先让整颗树都是 \(\texttt{X}\),把一个 \(\texttt{X}\) 改变成 \(\texttt{Y}\) 的影响。
手玩一下可以知道若为 \(\texttt{Y}\) 的节点的集合为 \(S\),则有 \(B = |S| - [1\in S], C = \sum\limits_{u\in S} |\operatorname{son}_u|\)。

再考虑到这题的特殊条件,\(|\operatorname{son}_u| = 2 \operatorname{or} 0\)。
那么就有 \(C = 2|S\cap \complement_{1, \cdots, n} \operatorname{leaf}|\),即 \(S\) 中非叶子结点的个数的 \(2\) 倍。

那么能发现 \(\frac{C}{2}\) 就是 \(S\) 中非叶子结点的个数,又因为 \(B = |S| - [1\in S]\),那么就可以知道 \(S\) 中的叶子节点个数为 \(B - \frac{C}{2} + [1\in S]\),对于这个 \([1\in S]\) 因为实际上就涉及 \(2\) 种情况是好处理的。
于是接下来的重点是是否存在 \(x\) 个非叶子节点与 \(y\) 个叶子节点的选取。

那么一个想法是用一个树形背包来合并信息,记 \(f_{u, y, x, 0 / 1}\) 为 \(u\) 节点子树内能否存在选了 \(y\) 个叶子节点 \(x\) 个非叶子节点且自身是否选了的方案,但显然是过不了的。

考虑到因为有 \(2\) 个限制,考虑固定下一边的限制。
例如考虑固定下叶子节点的个数 \(y\),判定是否存在 \(x\) 个非叶子结点的个数。

能够发现的是 \(x\) 是具有单调性的,也就是对于同样的子树与同样的 \(y\) 及同样该节点是否选取的情况,合法的 \(x\) 应当是一个前缀的。
即对于同样的 \(u, x, p\),应存在一个 \(\max x\),满足 \(f_{u, y, x, p} = [x\le \max x]\)。

那么就可以记 \(f_{u, y, p} = \max x\),用树形背包合并即可。

最后记得要讨论一下 \([1\in S]\)。

时间复杂度 \(\mathcal{O}(n^2)\)。

#include<bits/stdc++.h>
constexpr int inf = 1e9;
const int maxn = 1e4 + 10;
int fa[maxn], siz[maxn];
int f[maxn][maxn][2];
int ls[maxn], rs[maxn];
inline void solve() {
   int n, a, b, c; scanf("%d%d%d%d", &n, &a, &b, &c);
   for (int i = 1; i <= n; i++) ls[i] = rs[i] = 0;
   for (int i = 2; i <= n; i++) scanf("%d", &fa[i]), (ls[fa[i]] ? rs[fa[i]] : ls[fa[i]]) = i;
   if (c & 1)
      return puts("No"), void();
   for (int u = n; u; u--) {
      if (! ls[u]) {
         siz[u] = 1;
         f[u][0][0] = f[u][0][1] = 0;
         f[u][1][1] = 0, f[u][1][0] = -inf;
         continue;
      }
      siz[u] = u > 1 ? siz[ls[u]] + siz[rs[u]] : n;
      for (int i = 0; i <= siz[u]; i++)
         for (int j : {0, 1})
            f[u][i][j] = -1e9;
      for (int x : {0, 1})
         for (int i = 0; i <= siz[ls[u]]; i++)
            for (int j = 0; j <= siz[rs[u]]; j++)
               f[u][i + j][x] = std::max(f[u][i + j][x], f[ls[u]][i][x ^ 1] + f[rs[u]][j][x ^ 1] + x);
      if (u > 1)
         for (int i = 0; i <= siz[u]; i++)
            f[u][i][1] = std::max(f[u][i][1], f[u][i][0]);
   }
   puts((b >= c / 2 - 1 && f[1][b - c / 2 + 1][1] >= c / 2)
      || (b >= c / 2 && f[1][b - c / 2][0] >= c / 2) ? "Yes" : "No");
}
int main() {
   int T; scanf("%d", &T);
   while (T--) solve();
   return 0;
}

标签:Atcoder,XXYX,int,个数,texttt,Tree,叶子,maxn,节点
From: https://www.cnblogs.com/rizynvu/p/18444861

相关文章

  • Solution - Atcoder ARC157D YY Garden
    考虑到因为有横轴数轴两部分的限制,不妨先固定下来一部分的限制再处理另一部分。对于这题来说横轴竖轴本质是相同的,于是不妨考虑固定横轴。如果知道了横轴的分割,那么对于竖轴上就可以根据分割情况知道合法的分割了。即考虑记\(f_i\)为考虑了竖轴的前\(i\)列,第\(i\)列为最......
  • AtCoder Beginner Contest 365
    A-LeapYear思路模拟即可;AC代码#include<bits/stdc++.h>#defineendl'\n'#defineintintlonglong#definepbpush_back#definebsbitsetusingnamespacestd;typedefpair<char,int>PCI;typedefpair<......
  • CF280C Game on Tree题解
    题目描述给定一棵有根树,结点编号从1到n。根结点为1号结点。对于每一次操作,等概率的选择一个尚未被删去的结点并将它及其子树全部删去。当所有结点被删除之后游戏结束。也就是说,删除1号结点后游戏即结束。要求求出删除所有结点的期望操作次数。不是哥们,我好不容易国庆......
  • 题解:AtCoder Beginner Contest AT_abc373_d ABC373D Hidden Weights(格式美化版)
    题目传送门题目翻译给你一个NNN个点,MMM条边的有向图,其中边有边......
  • 力扣(leetcode)每日一题 1845 座位预约管理系统| treeSet和priority Queue的区别|线段树
    之前发过一篇,感觉还有深挖的地方,于是又补充一些信息这题目虽然是middle难度题目,要解答出来是只要easy的时间,但是深挖可以有hard的难度题解1可以帮助复习线段树的使用,题解2可以复习一下java基础知识题解1线段树这是自己憋出来的线段树classSeatManager{......
  • AtCoder Beginner Contest 365题解
    A-LeapYear按照题意模拟即可。codeB-SecondBest按照题意模拟即可。codeC-TransportationExpenses考虑当\(x\)增大时,\(\min(x,a_i)=x\)的项会越来越少。换言之,当\(x\)足够大时,\(ans=\suma_i\),若此时\(ans>M\)则说明无论补贴多少,这时答案都是一定的......
  • ant-table tree结构连线
    做一个类似这样的效果template<a-tableclass="custom-tree-table"rowKey="id":dataSource="tableData1":pagination="false":defaultExpandAllRows="true":expandable=&qu......
  • AtCoder Beginner Contest 371(ABCDE)
    A个人直接硬解,讨论情况也并不复杂代码:#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=1e6+10;voidsolve(){chara,b,c;cin>>a>>b>>c;if(a=='<'){if(c=='<......
  • 红黑树(Red-Black Tree):原理、常见算法及其应用
    目录引言红黑树的基本概念常见算法插入节点查找节点删除节点红黑树的应用场景1.数据库索引2.符号表3.动态集合总结优势对比自平衡条件旋转次数操作效率应用场景实现复杂度引言红黑树(Red-BlackTree)是一种自平衡的二叉查找树,它的设计目的是为了在最坏的......
  • AVLTree【c++实现】
    目录AVL树1.AVL树的概念2.AVLTree节点的定义3.AVLTree的插入4.AVLTree的旋转4.1左单旋4.2右单旋4.3左右双旋4.4右左双旋5.AVLTree的验证6.AVLTree的性能AVL树AVLTree的代码实现连接:AVLTree代码链接1.AVL树的概念学习了二叉搜索树之后,我们知道二叉搜索树虽可以......