#include <bits/stdc++.h>
#define int long long
using namespace std;
const int nmax = 1e5;
int n, m, k;
int t[nmax + 5];
vector<int> G[nmax + 5];
int d[nmax + 5], val[nmax + 5];
int w[nmax + 5], Max[nmax + 5];
vector<pair<pair<int,int>,int>> l;
struct arbore_de_intervale
{
    struct Node
    {
        int Min, Max;
        int lazy_set, lazy_add;
    };
    Node ai[4 * nmax + 5];
    Node Merge(Node a, Node b)
    {
        Node rez;
        rez.Max = max(a.Max, b.Max);
        rez.Min = min(a.Min, b.Min);
        rez.lazy_set = -1;
        rez.lazy_add = 0;
        return rez;
    }
    void propag(int nod)
    {
        if(ai[nod].lazy_add == 0 && ai[nod].lazy_set == -1)
        {
            return;
        }
        if(ai[nod].lazy_set != -1)
        {
            ai[nod * 2].Min = ai[nod * 2 + 1].Min = ai[nod].lazy_set;
            ai[nod * 2].Max = ai[nod * 2 + 1].Max = ai[nod].lazy_set;
            ai[nod * 2].lazy_set = ai[nod * 2 + 1].lazy_set = ai[nod].lazy_set;
            ai[nod].lazy_set = -1;
        }
        else
        {
            ai[nod * 2].Min += ai[nod].lazy_add;
            ai[nod * 2 + 1].Min += ai[nod].lazy_add;
            ai[nod * 2].Max += ai[nod].lazy_add;
            ai[nod * 2 + 1].Max += ai[nod].lazy_add;
            if(ai[nod * 2].lazy_set != -1)
            {
                ai[nod * 2].lazy_set += ai[nod].lazy_add;
                ai[nod * 2].lazy_add = 0;
            }
            else
            {
                ai[nod * 2].lazy_add += ai[nod].lazy_add;
            }
            ai[nod].lazy_add = 0;
        }
    }
    void update_set(int ua, int ub, int val, int nod, int a, int b)
    {
        if(ua <= a && ub >= b)
        {
            ai[nod].Min = ai[nod].Max = ai[nod].lazy_set = val;
            ai[nod].lazy_add = 0;
            return;
        }
        propag(nod);
        int mij = (a + b) >> 1;
        if(ua <= mij)
        {
            update_set(ua, ub, val, nod * 2, a, mij);
        }
        if(ub > mij)
        {
            update_set(ua, ub, val, nod * 2 + 1, mij + 1, b);
        }
        ai[nod] = Merge(ai[nod * 2], ai[nod * 2 + 1]);
    }
    void update_add(int ua, int ub, int val, int nod, int a, int b)
    {
        if(ua <= a && ub >= b)
        {
            if(ai[nod].lazy_set != -1)
            {
                ai[nod].lazy_set += val;
                ai[nod].lazy_add = 0;
            }
            else
            {
                ai[nod].lazy_add += val;
            }
            ai[nod].Max += val;
            ai[nod].Min += val;
            return;
        }
        propag(nod);
        int mij = (a + b) >> 1;
        if(ua <= mij)
        {
            update_add(ua, ub, val, nod * 2, a, mij);
        }
        if(ub > mij)
        {
            update_add(ua, ub, val, nod * 2 + 1, mij + 1, b);
        }
        ai[nod] = Merge(ai[nod * 2], ai[nod * 2 + 1]);
    }
    Node query(int qa, int qb, int nod, int a, int b)
    {
        if(qa <= a && qb >= b)
        {
            return ai[nod];
        }
        propag(nod);
        int mij = (a + b) >> 1;
        if(qa <= mij && qb > mij)
        {
            return Merge(query(qa, qb, nod * 2, a, mij), query(qa, qb, nod * 2 + 1, mij + 1, b));
        }
        if(qa <= mij)
        {
            return query(qa, qb, nod * 2, a, mij);
        }
        return query(qa, qb, nod * 2 + 1, mij + 1, b);
    }
    void parcurg(int nod, int a, int b)
    {
        if(ai[nod].Max == ai[nod].Min)
        {
            l.push_back({{a, b}, ai[nod].Min});
            return;
        }
        propag(nod);
        int mij = (a + b) >> 1;
        parcurg(nod * 2, a, mij);
        parcurg(nod * 2 + 1, mij + 1, b);
    }
    void init(int nod, int a, int b)
    {
        ai[nod].lazy_set = -1;
        if(a == b)
        {
            return;
        }
        int mij = (a + b) >> 1;
        init(nod * 2, a, mij);
        init(nod * 2 + 1, mij + 1, b);
    }
} ai[25];
void get_w(int nod)
{
    w[nod] = 1;
    Max[nod] = 0;
    for(auto it : G[nod])
    {
        get_w(it);
        w[nod] += w[it];
        if(w[it] > w[Max[nod]])
        {
            Max[nod] = it;
        }
    }
}
void dfs(int nod, int path = 1)
{
    if(path > 24)
    {
        while(true);
    }
    if(G[nod].size() == 0)
    {
        if(d[nod])
        {
            ai[path].update_set(d[nod], k, val[nod], 1, 1, k);
        }
        return;
    }
    dfs(Max[nod], path);
    for(auto it : G[nod])
    {
        if(it == Max[nod])
        {
            continue;
        }
        dfs(it, path + 1);
        l.clear();
        ai[path + 1].parcurg(1, 1, k);
        ai[path + 1].update_set(1, k, 0, 1, 1, k);
        for(auto upd : l)
        {
            ai[path].update_add(upd.first.first, upd.first.second, upd.second, 1, 1, k);
        }
    }
    if(d[nod])
    {
        int val_dp = ai[path].query(d[nod], d[nod], 1, 1, k).Max;
        int st = d[nod];
        int dr = k;
        int poz = 0;
        while(st <= dr)
        {
            int mij = (st + dr) >> 1;
            if(val_dp + val[nod] > ai[path].query(d[nod], mij, 1, 1, k).Max)
            {
                poz = mij;
                st = mij + 1;
            }
            else
            {
                dr = mij - 1;
            }
        }
        ai[path].update_set(d[nod], poz, val_dp + val[nod], 1, 1, k);
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    #ifdef home
    freopen("nr.in","r",stdin);
    freopen("nr.out","w",stdout);
    #endif // home
    cin>>n>>m>>k;
    for(int i=2;i<=n;i++)
    {
        cin>>t[i];
        G[t[i]].push_back(i);
    }
    for(int i=1;i<=m;i++)
    {
        int nod;
        cin>>nod;
        cin>>d[nod]>>val[nod];
    }
    for(int i=1;i<=24;i++)
    {
        ai[i].init(1, 1, k);
    }
    get_w(1);
    dfs(1);
    cout<<ai[1].ai[1].Max<<'\n';
    return 0;
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |