比赛 |
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;
}