题目大意:问一棵有根带权二叉树中最大的对称二叉树子树,对称二叉树为需满足将这棵树所有节点的左右子树交换,新树和原树对应位置的结构相同且点权相等。

题解:在对称二叉树中,对于深度相同的两个节点$u,v$,必定有$ls(u)=rs(v)$,$rs(u=ls(v)$,并且$val(u)=val(v)$,对每个点跑一遍深搜就可以了。发现跑一个点最多遍历它子树中较少的一棵子树。复杂度为$O(n\log_2n)$

卡点:

C++ Code:

#include <iostream>
#define maxn 1000010
#define ls(u) son[0][u]
#define rs(u) son[1][u]
int N, n, ans;
int V[maxn], son[2][maxn], sz[maxn];
bool check(int u, int v) {
if (!~u && !~v) return true;
if (~u && ~v && V[u] == V[v] && check(ls(u), rs(v)) && check(rs(u), ls(v))) return true;
return false;
}
void dfs(int u) {
sz[u] = 1;
if (~ls(u)) dfs(ls(u)), sz[u] += sz[ls(u)];
if (~rs(u)) dfs(rs(u)), sz[u] += sz[rs(u)];
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n;
for (int i = 1; i <= n; ++i) std::cin >> V[i];
for (int i = 1; i <= n; ++i) std::cin >> ls(i) >> rs(i);
dfs(1);
for (int i = 1; i <= n; ++i)
if (check(ls(i), rs(i))) ans = std::max(ans, sz[i]);
std::cout << ans << '\n';
return 0;
}

  

最新文章

  1. 解决Trauncate table没权限
  2. JS总结 本地对象1
  3. 简单又高效的Access分页语句
  4. [知识点]网络流之Edmond-Karp算法
  5. 在Xcode中使用C++与Objective-C混编
  6. sql优化--in和exists效率
  7. css实现三列布局,左右固定值,中间自适应。
  8. MySQL (五)--连接查询简介、 交叉连接、 内连接、外连接、自然连接、温馨小提示
  9. 使用Jenkins自动部署博客
  10. UltraEdit激活方法
  11. Debian系列软件管理(第二版)
  12. JCache只缓存部分字段
  13. Mybatis面试题
  14. 【Python】动手分析天猫内衣售卖数据,得到你想知道的信息
  15. JAVA 变量 数据类型 运算符 知识小结
  16. Connection reset by peer原理解析
  17. 字符加密 Valentino 函数 (伪分治)
  18. day_5.21 py 高级编程
  19. PopupMenu动态创建菜单
  20. PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和

热门文章

  1. Codeforces 1163E Magical Permutation [线性基,构造]
  2. Zuul超时配置
  3. mysql 添加表字段
  4. 证书转化 .cer .crt .jks
  5. 【CS224n】Lecture8 Notes
  6. Docker部署web项目-jar包
  7. RFC2119 规范内容
  8. (4)Flask项目模板渲染初体验
  9. Redis 操作帮助类
  10. 同时购入两台同款thinkpad笔记本电脑,分别使用同一账户激活office失败--------------解决方法(账户下有多个Office激活信息,重装后提示“许可证不正确或者最大激活次数”)