记录编号 583632 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 删除题目 最终得分 100
用户昵称 Gravatarop_组撒头屯 是否通过 通过
代码语言 C++ 运行时间 0.923 s
提交时间 2023-10-19 20:24:55 内存使用 12.72 MiB
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define clr(f,n) memset(f,0,sizeof(int)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(int)*(n))
const int N=100000+5;
const ll inf=0x3f3f3f3f3f3f3f3f;
int n;
ll w[N];
vector<int>g[N];
struct line{
	ll k,b;
}li[N];
ll calc(int i,int x){
	return li[i].k*x+li[i].b;
}
struct segtree{
	int lc[4*N],rc[4*N],id[4*N],tot=0;
	void clear(){
		tot=0;memset(id,0,sizeof(id));
		memset(lc,0,sizeof(lc)),memset(rc,0,sizeof(rc));
		return ;
	}
	void insert(int &pt,int l,int r,int cur){
		if (!pt){id[pt=++tot]=cur;return ;}
		int mid=(l+r)/2;
		if (calc(id[pt],mid)<calc(cur,mid))swap(id[pt],cur);
		if (calc(id[pt],l)>=calc(cur,l)&&calc(id[pt],r)>=calc(cur,r))return ;
		if (calc(id[pt],l)<calc(cur,l))insert(lc[pt],l,mid,cur);
		else insert(rc[pt],mid+1,r,cur);
		return ;
	}
	ll query(int pt,int l,int r,int pos){
		if (!pt)return -inf;
		int mid=(l+r)/2;ll ans=calc(id[pt],pos);
		if (pos<=mid)ans=max(ans,query(lc[pt],l,mid,pos));
		else ans=max(ans,query(rc[pt],mid+1,r,pos));
		return ans;
	}
	int merge(int p1,int p2,int l,int r){
		if (!p1||!p2)return p1|p2;
		insert(p1,l,r,id[p2]);
		int mid=(l+r)/2;
		lc[p1]=merge(lc[p1],lc[p2],l,mid);
		rc[p1]=merge(rc[p1],rc[p2],mid+1,r);
		return p1;
	}
}T;
int rt[N];
int dfn[N],tim=0,S[N],wson[N],pos[N];
void prework(int pt){
	S[pt]=1;dfn[pt]=++tim;pos[tim]=pt;
	for (auto v:g[pt]){
		prework(v);S[pt]+=S[v];
		if (S[v]>S[wson[pt]])wson[pt]=v;
	}return ;
}
ll f[N],ans=0;
void solve1(int pt){
	for (auto v:g[pt]){
		solve1(v);
		rt[pt]=T.merge(rt[pt],rt[v],1,n);
	}
	if (pt==1)return ;
	ll cur=T.query(rt[pt],1,n,S[pt]);
	f[pt]=max(-w[pt],cur-w[pt]);
	li[pt]={S[pt],f[pt]-1ll*S[pt]*S[pt]};
	T.insert(rt[pt],1,n,pt);
	ans=max(ans,f[pt]+1ll*S[pt]*(n-S[pt]));
	return ;
}
void solve2(int pt){
	if (wson[pt])solve2(wson[pt]);
	for (auto v:g[pt]){
		if (v==wson[pt])continue;
		solve2(v);
		for (int i=dfn[v];i<=dfn[v]+S[v]-1;i++){
			int x=pos[i];
			ll cur=T.query(rt[wson[pt]],1,n,S[x]);
			ans=max(ans,cur+f[x]+1ll*S[x]*(n-S[x]));
		}
		rt[wson[pt]]=T.merge(rt[wson[pt]],rt[v],1,n);
	}
	if (pt==1)return ;
	rt[pt]=rt[wson[pt]];
	li[pt]={-S[pt],f[pt]-1ll*S[pt]*S[pt]+1ll*n*S[pt]};
	T.insert(rt[pt],1,n,pt);
	return ;
}
int main(){
	freopen ("delete.in","r",stdin);
	freopen ("delete.out","w",stdout);
	scanf("%d",&n);
	for (int i=2;i<=n;i++){
		int p;scanf("%d%lld",&p,&w[i]);
		g[p].pb(i);
	}
	prework(1);
	solve1(1);
	T.clear(); 
	solve2(1);
	printf("%lld\n",ans);
	return 0;
}