P5803 [SEERC2019] Tree Permutations 题解
性质结论题。
思路#
以下的性质都是在
性质一:
有解的必要条件为
证明:
如果存在,那么点 在前 个点合法的前提下无法找到一个父亲,所以无法形成一棵树。
性质二:
在有解的情况下,对于
证明:
如果,那么点 及后面的点的父亲节点的编号必然不小于 ,所以一定会经过点 。
性质三:
证明:
显然。
推论:
在满足性质一,性质二的前提下,任意一条合法的
所以我们就只需要贪心的往路径中添加最小的点,查询最大的点的和就可以了。
时间复杂度:
Code#
/*
! 以渺小启程,以伟大结束。
! Created: 2024/06/29 20:55:24
*/
#include <bits/stdc++.h>
using namespace std;
#define fro(i, x, y) for (int i = (x); i <= (y); i++)
#define pre(i, x, y) for (int i = (x); i >= (y); i--)
const int N = 200010;
const int M = 131072;
using i64 = long long;
int n, m, tp, ct, a[N], b[N], v[N];
int sz[M << 1];
i64 vl[M << 1], ans[N];
inline void FAIL() { fro(i, 1, n - 1) cout << -1 << " "; exit(0); }
inline void add(int x, int c) { x += M; while (x) vl[x] += c, sz[x]++, x >>= 1; }
inline void del(int x, int c) { x += M; while (x) vl[x] -= c, sz[x]--, x >>= 1; }
inline auto ask(int p) {
i64 t = 1, res = 0;
while (p != 0) {
if (t > M) res += (t - M) * p, p = 0;
else if (p == sz[t]) res += vl[t], p -= sz[t];
else if (p <= sz[t << 1 | 1]) t = t << 1 | 1;
else res += vl[t << 1 | 1], p -= sz[t << 1 | 1], t = t << 1;
}
return res;
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n, m = n * 2 - 2;
fro(i, 1, m) cin >> a[i], b[a[i]] = 1;
sort(a + 1, a + m + 1);
fro(i, 1, m) add(a[i], a[i]);
fro(i, 1, n - 1) if (a[i] > i) FAIL();
fro(i, 1, n - 1) if (a[i] == i) v[i] = 1, ct++, del(i, i);
fill(ans + 1, ans + n, -1);
fro(i, 1, n - 1) {
if (b[i] && v[i] == 0) del(i, i), v[i] = 1, ct++;
ans[ct] = ask(ct);
}
fro(i, 1, n - 1) cout << ans[i] << " \n"[i == n - 1];
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)