安吉D11-C
1005 字
5 分钟
安吉D11-C
- 1安吉D19 T1
- 2安吉D19 T3
- 3安吉D20 模考12总结
- 4安吉D17 T3
- 5安吉D17 T4
- 6安吉D19 模考11总结
- 7安吉D15 A
- 8安吉D16 T4
- 9安吉D17 T1
- 10安吉D17 模考10总结
- 11安吉D16 T3
- 12安吉D16 模考9总结
- 13安吉D13 模考8总结
- 14安吉D13-T2
- 15安吉D13-T3
- 16安吉D12-T3
- 17安吉D11-B
- 18安吉D11-C本文
- 19安吉D11-D
- 20安吉D12 模考7总结
- 21安吉D12-T2
- 22安吉D11-A
- 23安吉D10 模考6总结
- 24安吉D10-T3
- 25安吉D10-T4
- 26安吉D8-E
- 27安吉D9-T4
- 28安吉D8-A
- 29安吉D8-B
- 30安吉D8-C
- 31安吉D8-D
- 32安吉D9 模考5总结
- 33安吉D9-T2
- 34安吉D9-T3
- 35安吉D6-T4
- 36安吉D4-G
- 37安吉D5-T2
- 38安吉D6 模考4总结
- 39安吉D6-T1
- 40安吉D6-T3
- 41安吉-开营测试 T4
- 42安吉D5 模考3总结
- 43安吉D5-T3
- 44安吉D4-A
- 45安吉D4-B
- 46安吉D4-C
- 47安吉D4:容斥原理
- 48安吉Day4-D
- 49安吉D3 模考2总结
- 50安吉D3-T1
- 51安吉D3-T2
- 52安吉D3-T4
- 53安吉D2 模考1总结
- 54安吉D2-T2
- 55安吉D1-G
- 56安吉D1-L
- 57安吉D2-T4
原题呈现
P3605 Promotion Counting P
题目描述
奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训——牛是可怕的管理者!
为了方便,把奶牛从 编号,把公司组织成一棵树,1 号奶牛作为总裁(这棵树的根节点).除了总裁以外的每头奶牛都有一个单独的上司(它在树上的 “双亲结点”).
所有的第 头牛都有一个不同的能力指数 ,描述了她对其工作的擅长程度.如果奶牛 是奶牛 的祖先节点,那么我们把奶牛 叫做 的下属.
不幸地是,奶牛们发现经常发生一个上司比她的一些下属能力低的情况,在这种情况下,上司应当考虑晋升她的一些下属.你的任务是帮助奶牛弄清楚这是什么时候发生的.简而言之,对于公司的中的每一头奶牛 ,请计算其下属满足 的 的数量.
输入格式
输入的第一行包括一个整数 .
接下来的 行包括奶牛们的能力指数 .保证所有数互不相同.
接下来的 行描述了奶牛 的上司的编号.再次提醒,1 号奶牛作为总裁,没有上司.
输出格式
输出包括 行.输出的第 行应当给出有多少奶牛 的下属比奶牛 能力高.
输入输出样例 #1
输入 #1
58042893848469308876816927787146369169577477941123输出 #1
20100说明/提示
对于 的数据,,.
既然是一棵树,不知道怎么做的时候就搜索.尝试 dfs,并在搜索时维护一些数据.
之后,我们观察到问题问的是:满足 的 的数量,要求有多少数大于(或小于)目标值,可以使用离散化 + 树状数组.
具体来说,我们遍历到一个节点 时:
- 查询当前树状数组中有多少数比 大.注意:现在树状数组中还没有加入过 的任何子孙节点.
- 遍历 子节点.
- 再次回到 时,树状数组已经完全收录的 的所有子孙节点.再次查询当前树状数组中有多少数比 大,与第一次查询的差值就是答案.
小技巧:树的 dfs 中两次查询时机
当我们在树上进行 dfs 搜索时,遍历到一个节点 ,在遍历其子节点前, 的子节点任意一个都没有被遍历,在遍历其子节点之后, 的所有子节点都会被遍历过.在两者之间,不会有不是 子节点的节点被遍历,因此,若是想要查询子节点的一些情况,可以在这两次查询时机各记录一次结果,然后考虑差量.
标程
#include <bits/stdc++.h>using namespace std;
const int N = 1e5 + 100;
int n, p[N], q[N], f[N], ans[N];vector<int> e[N];
struct BIT { int f[N]; int lowbit(int i) { return i & (-i); } void Modify(int pos, int v) { for (int i = pos; i <= n; i += lowbit(i)) { f[i] += v; } } int Query(int pos) { if (pos == 0) return 0; int ans = 0; for (int i = pos; i >= 1; i -= lowbit(i)) { ans += f[i]; } return ans; } int Query(int l, int r) { return Query(r) - Query(l - 1); }} bit;
void dfs(int u) { int tot = bit.Query(p[u] + 1, n); bit.Modify(p[u], 1); for (auto v : e[u]) { dfs(v); } ans[u] = bit.Query(p[u] + 1, n) - tot;}
signed main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> p[i]; q[i] = p[i]; } sort(q + 1, q + n + 1); for (int i = 1; i <= n; i++) { p[i] = lower_bound(q + 1, q + n + 1, p[i]) - q; } for (int i = 2; i <= n; i++) { cin >> f[i]; e[f[i]].push_back(i); } dfs(1); for (int i = 1; i <= n; i++) { cout << ans[i] << endl; } return 0;}文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!


