NC24048 [USACO 2017 Jan P]Promotion Counting
题目
题目描述
The cows have once again tried to form a startup company, failing to remember from past experience that cows make terrible managers!
The cows, conveniently numbered 1…N (), organize the company as a tree, with cow 1 as the president (the root of the tree). Each cow except the president has a single manager (its "parent" in the tree). Each cow i has a distinct proficiency rating, p(i), which describes how good she is at her job. If cow i is an ancestor (e.g., a manager of a manager of a manager) of cow j, then we say j is a subordinate of i.
Unfortunately, the cows find that it is often the case that a manager has less proficiency than several of her subordinates, in which case the manager should consider promoting some of her subordinates. Your task is to help the cows figure out when this is happening. For each cow i in the company, please count the number of subordinates j where p(j)>p(i).
输入描述
The first line of input contains N.
The next N lines of input contain the proficiency ratings p(1)…p(N) for the cows. Each is a distinct integer in the range 1…1,000,000,000.
The next N−1 lines describe the manager (parent) for cows 2…N. Recall that cow 1 has no manager, being the president.
输出描述
Please print N lines of output. The ith line of output should tell the number of subordinates of cow i with higher proficiency than cow i.
示例1
输入
5 804289384 846930887 681692778 714636916 957747794 1 1 2 3
输出
2 0 1 0 0
题解
知识点:DFS序,树状数组。
普通逆序对的公式是:
即从左到右枚举用时间轴维护先后关系,用树状数组维护数字大小关系。
类似地,我们求出树的dfn序,得到以 为根节点的子树的开始和结束序号 ,则树上逆序对公式是:
其中 需要时间轴的版本,单纯枚举是处理不了的。我们可以考虑用时间轴维护大小关系,先将 从大到小排序,那么公式转换为:
其中 ,在时间轴维护大小关系下,用树状数组即可求出区间出现过的数字个数。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; template<class T> class Fenwick { int n; vector<T> node; public: Fenwick(int _n = 0) { init(_n); } void init(int _n) { n = _n; node.assign(n + 1, T()); } void update(int x, T val) { for (int i = x;i <= n;i += i & -i) node[i] += val; } T query(int x) { T ans = T(); for (int i = x;i >= 1;i -= i & -i) ans += node[i]; return ans; } T query(int l, int r) { T ans = T(); ans += query(r); ans -= query(l - 1); return ans; } }; struct T { int sum; T &operator+=(const T &x) { return sum += x.sum, *this; } T &operator-=(const T &x) { return sum -= x.sum, *this; } }; const int N = 100007; pair<int, int> a[N]; vector<int> g[N]; int dfncnt; int L[N], R[N]; void dfs(int u) { L[u] = ++dfncnt; for (auto v : g[u]) dfs(v); R[u] = dfncnt; } int ans[N]; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i].first, a[i].second = i; sort(a + 1, a + n + 1, greater<pair<int, int>>()); for (int i = 2;i <= n;i++) { int u; cin >> u; g[u].push_back(i); } dfs(1); Fenwick<T> fw(n); for (int i = 1;i <= n;i++) { int u = a[i].second; ans[u] = fw.query(L[u], R[u]).sum; fw.update(L[u], { 1 }); } for (int i = 1;i <= n;i++) cout << ans[i] << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/17499388.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
2022-06-23 NC50038 kotori和糖果
2022-06-23 Contest
2022-06-23 NC19115 选择颜色
2022-06-23 NC23046 华华教月月做数学
2022-06-23 NC14731 逆序对
2022-06-23 NC15052 求最值
2022-06-23 NC50999 表达式计算4