Submission #1363165

#TimeUsernameProblemLanguageResultExecution timeMemory
1363165activedeltorreTree (IOI24_tree)C++20
0 / 100
2093 ms10916 KiB
#include "tree.h"
#include <cassert>
#include <cstdio>
#include <vector>
#include <map>

using namespace std;
int n;
std::vector<int> p, w;
vector<int>adj[60005];
long long dim[60005];
map<int,int>mp[60005];
int total[60005];
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;
    }
}
long long dfs(int curr,int L,int R)
{
    dim[curr]=0;
    total[curr]=0;
    mp[curr].clear();
    if(adj[curr].size()==0)
    {
        dim[curr]=L;
        total[curr]=0;
        return (long long)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);
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...