[NOIP2018 PJ T4]对称二叉树
2024-10-20 21:07:12
题目大意:问一棵有根带权二叉树中最大的对称二叉树子树,对称二叉树为需满足将这棵树所有节点的左右子树交换,新树和原树对应位置的结构相同且点权相等。
题解:在对称二叉树中,对于深度相同的两个节点$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;
}
最新文章
- 解决Trauncate table没权限
- JS总结 本地对象1
- 简单又高效的Access分页语句
- [知识点]网络流之Edmond-Karp算法
- 在Xcode中使用C++与Objective-C混编
- sql优化--in和exists效率
- css实现三列布局,左右固定值,中间自适应。
- MySQL (五)--连接查询简介、 交叉连接、 内连接、外连接、自然连接、温馨小提示
- 使用Jenkins自动部署博客
- UltraEdit激活方法
- Debian系列软件管理(第二版)
- JCache只缓存部分字段
- Mybatis面试题
- 【Python】动手分析天猫内衣售卖数据,得到你想知道的信息
- JAVA 变量 数据类型 运算符 知识小结
- Connection reset by peer原理解析
- 字符加密 Valentino 函数 (伪分治)
- day_5.21 py 高级编程
- PopupMenu动态创建菜单
- PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和
热门文章
- Codeforces 1163E Magical Permutation [线性基,构造]
- Zuul超时配置
- mysql 添加表字段
- 证书转化 .cer .crt .jks
- 【CS224n】Lecture8 Notes
- Docker部署web项目-jar包
- RFC2119 规范内容
- (4)Flask项目模板渲染初体验
- Redis 操作帮助类
- 同时购入两台同款thinkpad笔记本电脑,分别使用同一账户激活office失败--------------解决方法(账户下有多个Office激活信息,重装后提示“许可证不正确或者最大激活次数”)