Submission #1354387

#TimeUsernameProblemLanguageResultExecution timeMemory
1354387AvianshHarbingers (CEOI09_harbingers)C++20
70 / 100
1095 ms28620 KiB
#include <bits/stdc++.h>

using namespace std;

#define int long long

struct line{
    mutable long long m,c,p;
    bool operator<(const line &o) const {return m>o.m;}
    bool operator<(long long x) const {return p<x;}
};

///persistant lineContainer
struct lineContainer : multiset<line,less<>>{
    vector<vector<array<int,2>>>roll;
    const long long inf = 3e18;
    long long div(long long a, long long b){
        return (a/b)-((a%b)&&((a^b)<0));
    }
    bool isect(iterator x, iterator y){
        if(y==end()){
            x->p=inf;
            return 0;
        }
        if(x->m==y->m){
            x->p = (x->c<=y->c) ? inf : -inf;
        }
        else{
            x->p = div(x->c-y->c,y->m-x->m);
        }
        return x->p>=y->p;
    }
    void add(long long m, long long c, bool r=1){
        auto z = insert({m,c,-inf});
        vector<array<int,2>>arr;
        arr.push_back({m,c});
        int cnt = 1;
        auto y = z++;
        auto x = y;
        bool rel=1;
        while(isect(y,z)){
            if(r){
                arr.push_back({z->m,z->c});
                cnt++;
            }
            else{
                assert(0);
            }
            z=erase(z);
        }
        if(x!=begin() && isect(--x,y)){
            if(r){
                ///this must have deleted the initial which means this line doesnt matter
                rel=0;
                assert(y->m==m&&y->c==c);
                arr.push_back({y->m,y->c});
                cnt++;
            }
            else{
                assert(0);
            }
            isect(x,y=erase(y));
        }
        while((y=x)!=begin()&&(--x)->p>=y->p){
            if(r){
                arr.push_back({y->m,y->c});
                cnt++;
            }
            else{
                assert(0);
            }
            isect(x,erase(y));
        }
        if(r){
            if(rel){
                roll.push_back(arr);
            }
            else{
                arr.clear();
                roll.push_back(arr);
            }
        }
    }
    long long query(long long x){
        line l = *lower_bound(x);
        return l.m*x+l.c;
    }
    void rollback(){
        assert(roll.size());
        vector<array<int,2>>arr = roll.back();
        roll.pop_back();
        if(arr.size()==0){
            return;
        }
        auto l = lower_bound({arr[0][0],arr[0][1]});
        l=erase(l);
        if(l!=begin()){
            auto lef = l;
            lef--;
            isect(lef,l);
        }
        for(int i = 1;i<arr.size();i++){
            add(arr[i][0],arr[i][1],0);
        }
    }
};

void dfs(int st, vector<array<int,2>>g[], int dep, int p, long long dp[], int t[], int v[], lineContainer &lc){
    if(st){
        dp[st]=t[st]+v[st]*dep+lc.query(v[st]);
    }
    else{
        dp[st]=0;
    }
    lc.add(-dep,dp[st]);
    for(array<int,2>e:g[st]){
        if(e[0]==p)
            continue;
        dfs(e[0],g,dep+e[1],st,dp,t,v,lc);
    }
    lc.rollback();
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    vector<array<int,2>>g[n];
    for(int i = 0;i<n-1;i++){
        int u,v,d;
        cin >> u >> v >> d;
        u--;v--;
        g[u].push_back({v,d});
        g[v].push_back({u,d});
    }
    int t[n];
    int v[n];
    t[0]=0;
    v[0]=0;
    for(int i = 1;i<n;i++){
        cin >> t[i];
        cin >> v[i];
    }
    long long dp[n];
    lineContainer lc;
    dfs(0,g,0,-1,dp,t,v,lc);
    for(int i = 1;i<n;i++){
        cout << dp[i] << " ";
    }
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...