#include "tree.h"
#include <cassert>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
int n;
std::vector<int> p, w;
vector<int>adj[200005];
long long dim[200005];
map<int,int>mp[200005];
long long total[200005];
void merge(int curr,int fiu)
{
if(mp[fiu].size()>mp[curr].size())
{
swap(mp[fiu],mp[curr]);
}
for(auto k:mp[fiu])
{
mp[curr][k.first]+=k.second;
}
mp[fiu].clear();
}
long long dfs(int curr,long long L,long long R)
{
dim[curr]=0;
total[curr]=0;
mp[curr].clear();
if(adj[curr].size()==0)
{
dim[curr]=L;
total[curr]=0;
return L*w[curr];
}
long long cost=0;
for(auto k:adj[curr])
{
cost+=dfs(k,L,R);
dim[curr]+=dim[k];
total[curr]+=total[k];
merge(curr,k);
}
while(mp[curr].size() && (prev(mp[curr].end()))->first>=w[curr])
{
total[curr]-=(prev(mp[curr].end()))->second;
mp[curr].erase(prev(mp[curr].end()));
}
long long diff=dim[curr]-R;
while(mp[curr].size() && diff>0)
{
long long fre=(mp[curr].begin())->second;
long long cst=(mp[curr].begin())->first;
if(fre<=diff)
{
diff-=fre;
cost+=fre*cst;
total[curr]-=fre;
dim[curr]-=fre;
mp[curr].erase(mp[curr].begin());
}
else
{
cost+=diff*cst;
fre-=diff;
total[curr]-=diff;
dim[curr]-=diff;
mp[curr].begin()->second-=diff;
diff=0;
}
}
if(diff>0)
{
cost+=w[curr]*diff;
dim[curr]=R;
diff=0;
}
diff=dim[curr]-L;
while(total[curr]>diff)
{
auto it=prev(mp[curr].end());
long long fre=it->second;
long long cst=it->first;
mp[curr].erase(it);
if(total[curr]-fre<=diff)
{
fre=fre-(total[curr]-diff);
mp[curr][cost]=fre;
total[curr]=diff;
}
else
{
total[curr]-=fre;
}
}
if(total[curr]<dim[curr]-L)
{
total[curr]=dim[curr]-L;
mp[curr][w[curr]]+=dim[curr]-L;
}
return cost;
}
void init(std::vector<int> P, std::vector<int> W)
{
p = P;
w = W;
n = (int)p.size();
for(int i=1;i<n;i++)
{
adj[P[i]].push_back(i);
}
}
long long query(int L, int R)
{
return dfs(0,L,R);
}