记录编号 586576 评测结果 AAAAAAAAAA
题目名称 [ZJOI 2004] 树的果实 最终得分 100
用户昵称 Gravatar┭┮﹏┭┮ 是否通过 通过
代码语言 C++ 运行时间 0.698 s
提交时间 2024-02-07 23:16:17 内存使用 20.53 MiB
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
int n,m;
struct node{
	int id,p;
	bool operator < (const node x)const{//这里不加const会编译错误 
		return p < x.p;
	}
}a[N];
struct BIT{
	int c[N];
	int lowbit(int x){return (x & (-x));}
	void clear(){memset(c,0,sizeof c);}
	void add(int x,int z){
		for(;x <= n;x += lowbit(x))c[x] += z;
	}
	ll ask(int x){
		ll ans = 0;
		for(;x > 0;x -= lowbit(x))ans += c[x];
		return ans;
	}
}t;
struct made{
	int ver,nx;
}e[N<<1];
int hd[N],tot,cnt;
int dfn[N],siz[N],c[N],p[N];
ll A[N],B[N],C[N]; 
void add(int x,int y){
	tot++;
	e[tot].nx = hd[x],e[tot].ver = y,hd[x] = tot;
}
void dfs(int x){
	siz[x] = 1,dfn[x] = ++cnt;
	C[x] = t.ask(a[x].p-1);
	t.add(a[x].p,1);
	for(int i = hd[x];i;i = e[i].nx){
		int y = e[i].ver;
		dfs(y);
		siz[x] += siz[y];
	}
	t.add(a[x].p,-1);
}
void work(){
	sort(a+1,a+1+n);
	t.clear();
	for(int i = 1;i <= n;){
		int j = i;
		while(a[i].p == a[j].p){
			int x = a[i].id;
			A[x] = t.ask(dfn[x]+siz[x]-1) - t.ask(dfn[x]);
			B[x] = t.ask(n) - A[x]; 
			j++; 
		}
		while(i < j)t.add(dfn[a[i].id],1),i++;
	}
}
int main(){
	freopen("treesfruits.in","r",stdin);
	freopen("treesfruits.out","w",stdout);
	scanf("%d",&n);
	for(int i = 2;i <= n;i++){
		int x;scanf("%d",&x);
		add(x,i);
	}
	for(int i = 1;i <= n;i++)scanf("%d",&p[i]),c[i] = p[i];
	sort(c+1,c+1+n);
	m = unique(c+1,c+1+n) - (c+1);
	for(int i = 1;i <= n;i++){
		a[i].id = i;
		a[i].p = lower_bound(c+1,c+1+m,p[i]) - c;
		a[i].p = m + 1 - a[i].p;//把后缀和改为树状数组的前缀和 
	}
	t.clear();
	dfs(1);
	work();
	for(int i = 1;i <= n;i++)printf("%lld %lld %lld\n",A[i],B[i],C[i]);
	
	return 0;
	
}