记录编号 |
593450 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
删除题目 |
最终得分 |
100 |
用户昵称 |
┭┮﹏┭┮ |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
1.967 s |
提交时间 |
2024-09-02 19:03:23 |
内存使用 |
80.45 MiB |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define in inline
#define se second
#define mp make_pair
#define pb push_back
const int N = 1e5+10;
const ll inf = 1e18;
ll read(){
ll 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<<1) + (x<<3) + c-'0';
return x * f;
}
int n;
ll w[N];
struct line{
ll k,b = -inf;
line(ll k,ll b):k(k),b(b){}
line(){}
ll val(ll x){return k * x + b;}
};
bool cmp(line a,line b,ll x){return a.val(x) > b.val(x);}
int root[N];
struct LiChao_tree{
line mx[N<<5];int ls[N<<5],rs[N<<5],cnt;
void clear(){
cnt = 0;
memset(root,0,sizeof root);
for(int i = 0;i <= 32 * n;i++)mx[i] = {0,-inf},ls[i] = rs[i] = 0;
}
line ask(line a,line b,ll x){return cmp(a,b,x) ? a : b;}
void modify(int &p,int l,int r,line x){
if(l > r)return;
if(!p)return mx[p = ++cnt] = x,void();
int mid = l + r >> 1;
if(cmp(x,mx[p],mid))swap(x,mx[p]);
if(cmp(x,mx[p],l))modify(ls[p],l,mid,x);
if(cmp(x,mx[p],r))modify(rs[p],mid+1,r,x);
}
line cal(int p,int l,int r,ll x){
if(!p)return {0,-inf};
if(l == r)return mx[p];
int mid = l + r >> 1;
if(x <= mid)return ask(cal(ls[p],l,mid,x),mx[p],x);
else return ask(cal(rs[p],mid+1,r,x),mx[p],x);
}
int merge(int p,int q,int l,int r){
if(!p || !q)return p | q;
modify(p,l,r,mx[q]);
int mid = l + r >> 1;
ls[p] = merge(ls[p],ls[q],l,mid),rs[p] = merge(rs[p],rs[q],mid+1,r);
return p;
}
}t;
ll f[N],ans;
vector<int>e[N];
struct Tree{
int dfn[N],rnk[N],son[N],cnt;
ll siz[N];
void dfs1(int x){
dfn[x] = ++cnt,rnk[cnt] = x,siz[x] = 1;
for(int y : e[x]){
dfs1(y),siz[x] += siz[y];
if(!son[x] || siz[y] > siz[son[x]])son[x] = y;
}
}
void dp(int x){
for(int y : e[x]){
dp(y);
root[x] = t.merge(root[x],root[y],1,n);
}
f[x] = max(-w[x],t.cal(root[x],1,n,siz[x]).val(siz[x]) - w[x]);
t.modify(root[x],1,n,{siz[x],f[x] - siz[x] * siz[x]});
ans = max(ans,f[x] + siz[x] * (n - siz[x]));
}
void dfs2(int x){
for(int y : e[x]){
if(y == son[x])continue;
dfs2(y);
}
if(son[x])dfs2(son[x]);
for(int y : e[x]){
if(y == son[x])continue;
for(int i = dfn[y];i < dfn[y] + siz[y];i++){
int now = rnk[i];
ll val = t.cal(root[son[x]],1,n,siz[now]).val(siz[now]);
ans = max(ans,f[now] + siz[now] * (n - siz[now]) + val);
}
root[son[x]] = t.merge(root[son[x]],root[y],1,n);
}
root[x] = root[son[x]];
t.modify(root[x],1,n,{-siz[x],f[x] + siz[x] * (n - siz[x])});
}
}T;
int main(){
freopen("delete.in","r",stdin);
freopen("delete.out","w",stdout);
n = read();
for(int i = 2;i <= n;i++){
int x = read();w[i] = read();
e[x].pb(i);
}
T.dfs1(1),T.dp(1);
t.clear(),T.dfs2(1);
printf("%lld\n",ans);
return 0;
}