列表

详情


NC247496. Karashi的树 I

描述

给定一棵由个节点组成的有根树(个节点条边形成的无向连通图),根为点1。节点的权值为。定义点的“根路径”为根到点形成的路径序列,即;“根路径”权值序列即为
现在你可以执行以下操作若干次:
选择一个节点,将其“根路径”的权值序列翻转。具体地说,对于其“根路径”权值序列,更改。下图示例表示选择节点9进行操作。

定义这棵树的价值为每个节点的“根路径”权值序列之和的总和,即。求通过若干次操作后,这棵树的最大价值。

输入描述

第一行包括一个正整数,表示树的节点数;
第二行包括个正整数,第个数表示最初每个节点的权值;
第三行包括个正整数,第个数表示节点的父节点。

输出描述

输出一个正整数,表述经过若干次操作后,树的最大价值。

示例1

输入:

9
3 5 3 4 6 1 5 1 6
1 2 2 2 1 6 6 8

输出:

120

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 223ms, 内存消耗: 8744K, 提交时间: 2022-12-31 20:31:24

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=3e5+10;
LL a[N],b[N],c[N];
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],c[i]=1;
    for(int i=2;i<=n;i++) cin>>b[i];
    for(int i=n;i>=2;i--) c[b[i]]+=c[i];
    sort(a+1,a+1+n);
    sort(c+1,c+1+n);
    LL ans=0;
    for(int i=1;i<=n;i++)
        ans+=a[i]*c[i];
    cout<<ans;
}

C++(clang++ 11.0.1) 解法, 执行用时: 225ms, 内存消耗: 7952K, 提交时间: 2022-12-31 18:22:44

#include<bits/stdc++.h>
using namespace std;
const int m=3e5+10;
long long a[m],b[m],c[m],s=0;
int main()
{
	int n,i;
	cin>>n;
	for(i=1;i<=n;i++) cin>>a[i],c[i]=1;
	for(i=2;i<=n;i++) cin>>b[i];
	for(i=n;i>=2;i--) c[b[i]]+=c[i];
	sort(a+1,a+1+n);
	sort(c+1,c+1+n);
	for(i=1;i<=n;i++) s+=a[i]*c[i];
	cout<<s;
	return 0;
}

pypy3 解法, 执行用时: 423ms, 内存消耗: 60256K, 提交时间: 2022-12-30 21:07:17

n = int(input())
a = list(map(int, input().split()))
p = [0] + list(map(int, input().split()))
for i in range(n):
    p[i] -= 1
cnt = [1] * n
for i in range(1, n)[::-1]:
    cnt[p[i]] += cnt[i]
cnt.sort()
a.sort()
ans = 0
for i in range(n):
    ans += a[i] * cnt[i]
print(ans)
        

Python3 解法, 执行用时: 548ms, 内存消耗: 53464K, 提交时间: 2022-12-30 23:18:30

n = int(input())
a = list(map(int, input().split()))
p = [0] + list(map(int, input().split()))
for i in range(n):
    p[i] -= 1
cnt = [1] * n
for i in range(1, n)[::-1]:
    cnt[p[i]] += cnt[i]
cnt.sort()
a.sort()
ans = 0
for i in range(n):
    ans += a[i] * cnt[i]
print(ans)

上一题