给出
n
≤
2
e
5
n\leq2e5
n≤2e5个点,每个点都有一个权值,每条边的距离为
1
1
1。求所有点对的权值最大值和权值和。
只有两种情况,1:父亲的父亲;2:同一个结点的两个儿子。第一种情形多带一个参数即可维护。第二种情形对于最大值只要维护儿子权值的最大和次大值,对于求和只要维护权值和和权值平方和。
最大值是不用取模的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=2e5+7;
const int mod=1e4+7;
int w[N];
vector<int> go[N];
int ans=0,sum=0;
void dfs(int u,int f,int gf) {
int mxf=-1,mxs=-1;
ll s=0,sq=0;
for(auto &v:go[u]) {
if(v==f) continue;
s+=w[v],sq+=1LL*w[v]*w[v];
if(w[v]>=mxf) mxs=mxf,mxf=w[v];
else if(w[v]>mxs) mxs=w[v];
dfs(v,u,f);
}
if(mxf!=-1&&mxs!=-1) ans=max(ans,mxf*mxs);
if(gf!=-1) ans=max(ans,w[u]*w[gf]),sum=(sum+2*w[u]*w[gf])%mod;
sum=(sum+(s*s-sq)%mod)%mod;
}
int main() {
int n;
scanf("%d",&n);
for(int i=1;i<n;i++) {
int u,v;
scanf("%d%d",&u,&v);
go[u].push_back(v);
go[v].push_back(u);
}
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
dfs(1,-1,-1);
printf("%d %d\n",ans,sum);
return 0;
}