Submission #283505

#TimeUsernameProblemLanguageResultExecution timeMemory
283505dooweyMagic Tree (CEOI19_magictree)C++14
100 / 100
989 ms58484 KiB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, ll> pii;

#define fi first
#define se second
#define mp make_pair
#define fastIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

const int N = (int)1e5 + 10;
vector<int> T[N];

struct Node{
    ll val;
    ll lazy;
};

Node G[N * 4 + 512];

void push(int node, int cl, int cr){
    G[node].val += G[node].lazy;
    if(cl != cr){
        G[node * 2].lazy += G[node].lazy;
        G[node * 2 + 1].lazy += G[node].lazy;
    }
    G[node].lazy = 0;
}

void upd(int node, int cl, int cr, int tl, int tr, ll v){
    push(node, cl, cr);
    if(cr < tl || cl > tr) return;
    if(cl >= tl && cr <= tr){
        G[node].lazy = v;
        push(node, cl, cr);
        return;
    }
    int mid = (cl + cr) / 2;
    upd(node * 2, cl, mid, tl, tr, v);
    upd(node * 2 + 1, mid + 1, cr, tl, tr, v);
    G[node].val = max(G[node * 2].val, G[node * 2 + 1].val);
}

ll get(int node, int cl, int cr, int tl, int tr){
    push(node, cl, cr);
    if(cr < tl || cl > tr)
        return 0ll;
    if(cl >= tl && cr <= tr){
        return G[node].val;
    }
    int mid = (cl + cr) / 2;
    return max(get(node * 2, cl, mid, tl, tr), get(node * 2 + 1, mid + 1, cr, tl, tr));
}

int k;

int sub[N];

void dfs(int u){
    sub[u] = 1;
    for(auto x : T[u]){
        dfs(x);
        sub[u] += sub[x];
    }
}

set<int> ff[N];
set<pii> res[N];
int tr[N], ww[N];

struct R{
    int lef;
    int rig;
    ll ch;
};

vector<R> rev[N];

void dfs1(int u, bool keep){
    int id = -1;
    for(auto x : T[u]){
        if(id == -1 || sub[x] > sub[id])
            id = x;
    }
    for(auto x : T[u]){
        if(x != id){
            dfs1(x, false);
            for(auto y : ff[x]){
                ff[u].insert(y);
            }
            ff[x].clear();
        }
    }
    if(id != -1){
        dfs1(id, true);
        swap(ff[u], ff[id]);
        for(auto y : ff[id]){
            ff[u].insert(y);
        }
        ff[id].clear();
        swap(rev[u], rev[id]);
    }
    for(auto x : T[u]){
        if(x != id){
            int las = 0;
            ll cv = -1;
            for(auto y : res[x]){
                if(las != 0){
                    upd(1, 1, k, las, y.fi - 1, cv);
                    rev[u].push_back({las, y.fi - 1, cv});
                }
                las = y.fi;
                cv = y.se;
            }
            if(las != 0){
                upd(1, 1, k, las, k, cv);
                rev[u].push_back({las, k, cv});
            }
        }
    }
    if(tr[u] > 0){
        ff[u].insert(tr[u]);
        auto it = ff[u].find(tr[u]);
        auto nx = it;
        nx ++ ;
        int op, en;
        ll upd_v = get(1, 1, k, tr[u], tr[u]) + ww[u];
        ll cur_v;
        while(1){
            op = *it;
            if(nx == ff[u].end()){
                en = k;
            }
            else{
                en = *nx - 1;
            }
            cur_v = get(1, 1, k, en, en);
            if(cur_v >= upd_v) break;
            upd(1, 1, k, op, en, upd_v - cur_v);
            rev[u].push_back({op, en, upd_v - cur_v});
            if(nx==ff[u].end())
                break;
            nx++;
            it=ff[u].erase(it);
        }
        ff[u].insert(tr[u]);
    }

    if(!keep){
        for(auto x : ff[u]){
            res[u].insert(mp(x, get(1, 1, k, x, x)));
        }
        for(auto f : rev[u]){
            upd(1, 1, k, f.lef, f.rig, -f.ch);
        }
        rev[u].clear();
    }
}


int main(){
    fastIO;
    int n, m;
    cin >> n >> m >> k;
    int p;
    for(int i = 2; i <= n; i ++ ){
        cin >> p;
        T[p].push_back(i);
    }
    int id;
    for(int i = 1; i <= m ; i ++ ){
        cin >> id >> tr[id] >> ww[id];
    }
    dfs(1);
    dfs1(1, true);
    cout << G[1].val;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...