比赛 4043级2023省选练习赛1 评测结果 AAAAAAAAAA
题目名称 树的果实 最终得分 100
用户昵称 zxhhh 运行时间 1.350 s
代码语言 C++ 内存使用 26.08 MiB
提交时间 2023-03-03 20:40:36
显示代码纯文本
#include <bits/stdc++.h>
#define lowbit(a) ((a) & (-a))

using namespace std;

const int N = 1e5 + 5;

int n, p[N], a[N], t[N], c[N], dfn[N], cnt[N], idx, l[N], r[N], sm[N];
int pre[N << 2];
vector <int> e[N];

struct node {
	int l, r, x, idx;
}nodes[N << 2], tmp[N << 2];

inline void add (int idx, int x) {
	while (idx <= n) c[idx] += x, idx += lowbit(idx);
}

inline int query (int idx) {
	int res = 0; while (idx) res += c[idx], idx -= lowbit(idx); return res;
}

void dfs (int p, int s) {
//	cout << p;
	add(a[p], 1); cnt[p] = s - query(a[p]); dfn[++idx] = p; l[p] = idx;
	for (int i = 0;i < e[p].size();i++) {
		int y = e[p][i]; dfs(y, s + 1);
	}
	add(a[p], -1); r[p] = idx;
}

bool cmp (node a, node b) {
	if (a.l != b.l) return a.l > b.l;
	if (a.idx == -1) return 1; return 0;
}

void cdq (int l, int r) {
	if (l == r) return;
	int mid = (l + r) >> 1, o = 0, tl = l, tr = mid + 1;
	cdq (l, mid); cdq (mid + 1, r);
	for (int i = l;i <= r;i++) {
		if ((tr > r) || (tl <= mid && nodes[tl].r <= nodes[tr].r)) {
			if (nodes[tl].idx == -1) add (nodes[tl].x, 1), pre[++o] = nodes[tl].x;
			tmp[i] = nodes[tl++];
		} 
		else {
			if (nodes[tr].idx != -1) sm[nodes[tr].idx] += query(nodes[tr].x - 1);
			tmp[i] = nodes[tr++];
		}
	}
	for (int i = l;i <= r;i++) nodes[i] = tmp[i];
	for (int i = 1;i <= o;i++) add(pre[i], -1);
}

int main () {
	freopen("treesfruits.in", "r", stdin);
	freopen("treesfruits.out", "w", stdout);
	scanf("%d", &n);
	for (int i = 2;i <= n;i++) scanf("%d", &p[i]), e[p[i]].push_back(i);
	for (int i = 1;i <= n;i++) scanf("%d", &a[i]), t[i] = a[i];
	sort (t + 1, t + 1 + n); for (int i = 1;i <= n;i++) a[i] = lower_bound(t + 1, t + 1 + n, a[i]) - t; 
	dfs(1, 1); idx = 0;
	for (int i = 1;i <= n;i++) nodes[++idx] = (node){l[i], l[i], a[i], -1}, nodes[++idx] = (node){l[i] + 1, r[i], a[i], i};
//	for (int i = 1;i <= n;i++) cout <<a[i] << " " << l[i] << " " << r[i] << endl;
	sort (nodes + 1, nodes + 1 + idx, cmp);
//	for (int i = 1;i <= idx;i++) printf("%d %d %d %d\n", nodes[i].l, nodes[i].r, nodes[i].x, nodes[i].idx); 
//	cout << 1;
//cout << endl;
	cdq(1, idx);
	
	for (int i = 1;i <= n;i++) printf("%d %d %d\n", r[i] - l[i] - sm[i], (n - a[i]) - (r[i] - l[i] - sm[i]), cnt[i]);
	return 0;
}