給定一棵樹,每次操作選取一個從根節點開始的路徑,對於路徑上的第 ii 個點,其值加上 cic_i,其中 cc 是一個不降非負整數序列。最終使得對於第 ii 個節點,其值在 lil_irir_i 之間。求最少運算元。

考慮貪心,從葉子開始,儘可能讓每個節點加的數大。fif_i 表示節點 ii 所能加上去的最大值。

void solve()
{
    int n;
    scanf("%d", &n);
    std::vector<std::vector<int>> g(n + 1);
    std::vector<int> l(n + 1), r(n + 1);
    std::vector<long long> f(n + 1);
    for (int i = 2; i <= n; i++)
    {
        int p;
        scanf("%d", &p);
        g[p].push_back(i);
    }
    for (int i = 1; i <= n; i++) scanf("%d%d", &l[i], &r[i]);
    int ans = 0;
    for (int i = n; i >= 1; i--)
    {
        long long sum = 0;
        f[i] = r[i];
        for (auto j : g[i])
        {
            sum += f[j];
        }   
        if (sum < l[i])
            ans++;
        else
            f[i] = std::min(sum, f[i]);
    }
    printf("%d\n", ans);
}