#include <bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const long long mod = 1e9 + 7;
const int MaxN = 1e6 + 5;
const int MaxLog = 20;
struct Star
{
    int x, y, a, b;
    long long c;
};
int n, m;
int arr[MaxN];
Star add[MaxN];
void Inp()
{
    cin >> n;
    for (int x = 1; x <= n; x++)
    {
        cin >> arr[x];
        arr[x] = n - arr[x];
    }
    cin >> m;
    for (int x = 1; x <= m; x++)
    {
        cin >> add[x].x >> add[x].y >> add[x].c;
        add[x].y = n - add[x].y + 1;
    }
}
int root;
pair<int, int> graph[MaxN];
void BuildTree()
{
    for (int x = 1; x <= n; x++)
    {
        graph[x] = make_pair(-1, -1);
    }
    stack<int> st;
    for (int x = 1; x <= n; x++)
    {
        int pre = -1;
        while (!st.empty() && arr[st.top()] >= arr[x])
        {
            pre = st.top();
            st.pop();
        }
        if (st.empty())
        {
            graph[x].first = pre;
            root = x;
        }
        else
        {
            graph[x].first = pre;
            graph[st.top()].second = x;
        }
        st.push(x);
    }
}
int par[MaxN];
int h[MaxN];
void PreDFS(int u)
{
    if (graph[u].first != -1)
    {
        h[graph[u].first] = h[u] + 1;
        par[graph[u].first] = u;
        PreDFS(graph[u].first);
    }
    if (graph[u].second != -1)
    {
        h[graph[u].second] = h[u] + 1;
        par[graph[u].second] = u;
        PreDFS(graph[u].second);
    }
}
int BinLift[MaxLog][MaxN];
void Build()
{
    for (int x = 1; x <= n; x++)
    {
        BinLift[0][x] = par[x];
    }
    for (int x = 1; x < MaxLog; x++)
    {
        for (int y = 1; y <= n; y++)
        {
            BinLift[x][y] = BinLift[x - 1][BinLift[x - 1][y]];
        }
    }
}
struct Node
{
    int lc, rc, l, r;
    long long res, lazyadd, lazymx;
    Node(int _l = 0, int _r = 0, long long _res = 0)
    {
        l = _l;
        r = _r;
        lc = rc = -1;
        res = _res;
        lazyadd =  0;
        lazymx = -inf;
    }
};
int curPos;
Node SegTree[8 * MaxN];
void Fix(int pos)
{
    Node& p = SegTree[pos];
    if (p.lazyadd == 0 && p.lazymx == -inf)
    {
        return;
    }
    p.res = max(p.res, p.lazymx) + p.lazyadd;
    if (p.lc != -1)
    {
        SegTree[p.lc].lazymx = max(SegTree[p.lc].lazymx, p.lazymx - SegTree[p.lc].lazyadd);
        SegTree[p.lc].lazyadd += p.lazyadd;
    }
    if (p.rc != -1)
    {
        SegTree[p.rc].lazymx = max(SegTree[p.rc].lazymx, p.lazymx - SegTree[p.rc].lazyadd);
        SegTree[p.rc].lazyadd += p.lazyadd;
    }
    p.lazyadd = 0;
    p.lazymx = -inf;
}
void MakeChild(int pos)
{
    Fix(pos);
    Node& p = SegTree[pos];
    int l = p.l, r = p.r;
    if (l == r)
    {
        return;
    }
    int mid = (l + r) >> 1;
    if (p.lc == -1)
    {
        curPos++;
        SegTree[curPos] = Node(l, mid, p.res);
        p.lc = curPos;
    }
    if (p.rc == -1)
    {
        curPos++;
        SegTree[curPos] = Node(mid + 1, r, p.res);
        p.rc = curPos;
    }
}
void UpdateAdd(int pos, int i, int j, long long u)
{
    Fix(pos);
    Node& p = SegTree[pos];
    int l = p.l, r = p.r;
    if (j < l || r < i)
    {
        return;
    }
    if (i <= l && r <= j)
    {
        p.lazyadd += u;
        Fix(pos);
        return;
    }
    MakeChild(pos);
    UpdateAdd(p.lc, i, j, u);
    UpdateAdd(p.rc, i, j, u);
    p.res = max(SegTree[p.lc].res, SegTree[p.rc].res);
}
void UpdateMx(int pos, int i, int j, long long u)
{
    Fix(pos);
    Node& p = SegTree[pos];
    int l = p.l, r = p.r;
    if (j < l || r < i)
    {
        return;
    }
    if (i <= l && r <= j)
    {
        p.lazymx = max(p.lazymx, u - p.lazyadd);
        Fix(pos);
        return;
    }
    MakeChild(pos);
    UpdateMx(p.lc, i, j, u);
    UpdateMx(p.rc, i, j, u);
    p.res = max(SegTree[p.lc].res, SegTree[p.rc].res);
}
long long Get(int pos, int i, int j)
{
    Fix(pos);
    Node& p = SegTree[pos];
    int l = p.l, r = p.r;
    if (j < l || r < i)
    {
        return 0;
    }
    if (i <= l && r <= j)
    {
        return p.res;
    }
    MakeChild(pos);
    return max(Get(p.lc, i, j), Get(p.rc, i, j));
}
int Merge(int pos1, int pos2)
{
    Fix(pos1);
    Fix(pos2);
    Node& p = SegTree[pos1];
    Node& q = SegTree[pos2];
    if (p.lc == -1 && p.rc == -1)
    {
        q.lazymx = max(q.lazymx, p.res - q.lazyadd);
        Fix(pos2);
        return pos2;
    }
    if (q.lc == -1 && q.rc == -1)
    {
        p.lazymx = max(p.lazymx, q.res - p.lazyadd);
        Fix(pos1);
        return pos1;
    }
    p.lc = Merge(p.lc, q.lc);
    p.rc = Merge(p.rc, q.rc);
    p.res = max(SegTree[p.lc].res, SegTree[p.rc].res);
    return pos1;
}
int curST[MaxN];
vector<int> mark[MaxN];
long long F[MaxN];
void DFS(int u)
{
    curPos++;
    SegTree[curPos] = Node(1, n, 0);
    curST[u] = curPos;
    long long s = 0;
    if (graph[u].first != -1)
    {
        DFS(graph[u].first);
        s += F[graph[u].first];
    }
    if (graph[u].second != -1)
    {
        DFS(graph[u].second);
        s += F[graph[u].second];
    }
    if (graph[u].first != -1 && graph[u].second != -1)
    {
        UpdateAdd(curST[graph[u].first], 1, n, F[graph[u].second]);
        UpdateAdd(curST[graph[u].second], 1, n, F[graph[u].first]);
    }
    if (graph[u].first != -1)
    {
        curST[u] = Merge(curST[u], curST[graph[u].first]);
    }
    if (graph[u].second != -1)
    {
        curST[u] = Merge(curST[u], curST[graph[u].second]);
    }
    for (int x : mark[u])
    {
        //cout << u << " " << add[x].b << " " << add[x].c << "\n";
        UpdateMx(curST[u], 1, h[add[x].b], s + add[x].c);
    }
    F[u] = Get(curST[u], h[u], n);
    //cout << Get(curST[u], 1, 1) << ":" << u << ":" << F[u] << "\n";
}
void Exc()
{
    BuildTree();
    h[root] = 1;
    PreDFS(root);
    Build();
    long long res = 0;
    for (int x = 1; x <= m; x++)
    {
        add[x].a = add[x].x;
        add[x].b = add[x].x;
        for (int y = MaxLog - 1; y >= 0; y--)
        {
            if (arr[BinLift[y][add[x].b]] >= add[x].y)
            {
                add[x].b = BinLift[y][add[x].b];
            }
        }
        mark[add[x].a].push_back(x);
        res += add[x].c;
    }
    DFS(root);
    cout << res - F[root];
}
int main()
{
    //freopen("D.INP", "r", stdin);
    //freopen("D.OUT", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int test = 1;
    //cin >> test;
    for (int x = 1; x <= test; x++)
    {
        Inp();
        Exc();
    }
    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... |