比赛 CSP2023-S模拟赛 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 删除题目 最终得分 100
用户昵称 YunQian 运行时间 5.779 s
代码语言 C++ 内存使用 70.43 MiB
提交时间 2023-10-17 21:33:36
显示代码纯文本
#include<bits/stdc++.h>

#define ll long long

using namespace std;

inline int read(){
	int x=0,f=1;char c=getchar();
	for(;(c<'0'||c>'9');c=getchar()){if(c=='-')f=-1;}
	for(;(c>='0'&&c<='9');c=getchar())x=x*10+(c&15);
	return x*f;
}

void cmax(int &x,int v){x=max(x,v);}
void cmin(int &x,int v){x=min(x,v);}

const int N=1e5+5;
vector<pair<int,int> >G[N];
int n;

#define fi first
#define se second
#define mk make_pair

#define to fi
#define cost se

namespace Tree{
	int fa[N],dfn[N],dep[N],top[N],hson[N],sz[N];

	void dfs1(int u,int de){
		dep[u]=de,sz[u]=1;
		for(auto e:G[u]){
			int v=e.to;
			if(v==fa[u])continue;
			fa[v]=u,dfs1(v,de+1),sz[u]+=sz[v];
			if(sz[v]>sz[hson[u]])hson[u]=v;
		}
	}
	
	int tot=0,id[N];
	void dfs2(int u,int tp){
		top[u]=tp,dfn[u]=++tot,id[dfn[u]]=u;
		if(hson[u])dfs2(hson[u],tp);
		for(auto e:G[u]){
			int v=e.to;
			if(v==hson[u]||v==fa[u])continue;
			dfs2(v,v);
		}
	}
	
	int find(int u,int v){
		int de=dep[u]+1;
		while(dep[top[v]]>de)v=fa[top[v]];
		int dis=dep[v]-de;
		return id[dfn[v]-dis];
	}

	int root=1;
	void build(){dfs1(1,1),dfs2(1,1);}
	bool is_anc(int u,int v){return dfn[u]<=dfn[v]&&dfn[v]<=dfn[u]+sz[u]-1;}
	void makeroot(int u){root=u;}
	int getsz(int u){
		if(u==root)return n;
		if(is_anc(u,root)){
			int v=find(u,root);
			return n-sz[v];
		}
		else return sz[u];
	}
};

using Tree::makeroot;
using Tree::getsz;

int mx[N],sz[N],rt,all;
bool vis[N];

void getroot(int u,int fa){
	sz[u]=1,mx[u]=0;
	for(auto e:G[u]){
		int v=e.to;
		if(v==fa||vis[v])continue;
		getroot(v,u),sz[u]+=sz[v],mx[u]=max(mx[u],sz[v]);
	}
	mx[u]=max(mx[u],all-sz[u]);
	if(mx[u]<mx[rt]||rt==0)rt=u;
}

const ll INF=1e14;

struct LINE{
	ll k,b;
	LINE(ll K,ll B):k(K),b(B){}
	LINE(){}
	ll val(ll x){return k*x+b;}
};
bool operator==(LINE X,LINE Y){return X.k==Y.k&&X.b==Y.b;}
bool chk(LINE A,LINE B,ll pos){
	return A.val(pos)>B.val(pos);
}

struct LiChao_SegTree{
	LINE d[N<<5];int ls[N<<5],rs[N<<5],tot;
	int cnt,b[N<<5];
	void del(int p){d[p]=LINE(0,-INF),ls[p]=rs[p]=0;b[++cnt]=p;}
	int build(){if(cnt>0)return b[cnt--];return ++tot;}
	#define ls(p) (ls[p])
	#define rs(p) (rs[p])
	void clear(){for(int i=0;i<=tot;i++)d[i]=LINE(0,-INF),ls[i]=rs[i]=0;tot=cnt=0;}
	void init(){for(int i=0;i<(N<<4);i++)d[i]=LINE(0,-INF),ls[i]=rs[i]=0;tot=cnt=0;}
	void upd(int &p,int ql,int qr,LINE A){
		if(!p){p=build(),d[p]=A;return ;}
		int mid=(ql+qr)>>1;
		if(chk(A,d[p],mid))swap(d[p],A);
		if(chk(A,d[p],ql))upd(ls(p),ql,mid,A);
		else if(chk(A,d[p],qr))upd(rs(p),mid+1,qr,A);
	}
	void ins(int l,int r,LINE A,int ql,int qr,int &p){
		if(!p)p=build(),d[p]=LINE(0,-INF);
		if(l<=ql&&qr<=r){upd(p,ql,qr,A);return ;}
		int mid=(ql+qr)>>1;
		if(l<=mid)ins(l,r,A,ql,mid,ls(p));
		if(r>mid)ins(l,r,A,mid+1,qr,rs(p));
	}
	LINE qmax(int x,int ql,int qr,int p){
		if(!p)return LINE(0,-INF);
		int mid=(ql+qr)>>1;ll now=d[p].val(x);LINE nl=d[p];
		if(x<=mid){
			LINE nr=qmax(x,ql,mid,ls(p));
			if(now>nr.val(x))return nl;
			return nr;
		}
		else{
			LINE nr=qmax(x,mid+1,qr,rs(p));
			if(now>nr.val(x))return nl;
			return nr;
		}
	}
	int merge(int p,int q,int l,int r){
		if(!p||!q)return p+q;
		if(l==r){d[p]=(d[p].val(l)>d[q].val(l)?d[p]:d[q]);del(q);return p;}
		int mid=(l+r)>>1;
		ls[p]=merge(ls(p),ls(q),l,mid),rs[p]=merge(rs(p),rs(q),mid+1,r);
		upd(p,l,r,d[q]);del(q);
		return p;
	}
}T;

ll f[N];
int wf[N],root[N],siz[N];

void dfs(int u,int fa){
	siz[u]=getsz(u);
	for(auto e:G[u]){
		int v=e.to,w=e.cost;
		if(v==fa||vis[v])continue;
		wf[v]=w,dfs(v,u);
	}
}

void DP(int u,int fa){
	f[u]=-wf[u];
	for(auto e:G[u]){
		int v=e.to;
		if(v==fa||vis[v])continue;
		DP(v,u),root[u]=T.merge(root[u],root[v],1,n);
	}
	f[u]=max(f[u],T.qmax(siz[u],1,n,root[u]).val(siz[u])-wf[u]);
	T.ins(1,n,LINE(siz[u],f[u]-1ll*siz[u]*siz[u]),1,n,root[u]);
}

int Root=0;
void addq(int u,int fa){
	T.ins(1,n,LINE(-siz[u],f[u]+1ll*(n-siz[u])*siz[u]),0,n,Root);
	for(auto e:G[u]){
		int v=e.to;
		if(v==fa||vis[v])continue;
		addq(v,u);
	}
}

ll ans=0;
void calc(int u,int fa){
	ans=max(ans,f[u]+1ll*(n-siz[u])*siz[u]);
	ans=max(ans,T.qmax(siz[u],1,n,Root).val(siz[u])+f[u]+1ll*(n-siz[u])*siz[u]);
	for(auto e:G[u]){
		int v=e.to;
		if(v==fa||vis[v])continue;
		calc(v,u);
	}
}

void clear(int u,int fa){
	wf[u]=f[u]=siz[u]=root[u]=0;
	for(auto e:G[u]){
		int v=e.to;
		if(v==fa||vis[v])continue;
		clear(v,u);
	}
}

void solve(int u){
	makeroot(u);
	for(auto e:G[u]){
		int v=e.to,w=e.cost;
		if(vis[v])continue;
		wf[v]=w,dfs(v,u),DP(v,u);
	}
	
	Root=0;T.clear();
	for(auto e:G[u]){
		int v=e.to;
		if(vis[v])continue;
		calc(v,u),addq(v,u);
	}
	
	T.clear();clear(u,0);
}

void dfz(int u){
	solve(u),vis[u]=1;
	for(auto e:G[u]){
		int v=e.to;
		if(vis[v])continue;
		rt=0,all=sz[v],getroot(v,u),getroot(rt,u),dfz(rt);
	}
}

signed main(void){

	freopen("delete.in","r",stdin);
	freopen("delete.out","w",stdout);

	n=read();
	for(int i=2;i<=n;i++){
		int p=read(),w=read();
		G[p].emplace_back(mk(i,w)),G[i].emplace_back(mk(p,w));
	}
	
	Tree::build();
	rt=0,all=n,getroot(1,0),getroot(rt,0),dfz(rt);
	
	cout<<ans<<endl;

	return 0;
}