1 条题解

  • 0
    @ 2026-10-18 23:39:02

    果园巡查

    思路与复杂度

    先迭代遍历获得父在子前的顺序,再逆序处理。节点数量为1加左右子树数量,果实总数为自身果实加左右子树总数。0号空节点的两项均为0。时间和空间 O(n),用64位整数累计,迭代实现避免20万层递归栈溢出。

    正确性与边界

    从叶到根归纳,左右子树不重叠且与当前节点一起构成整棵子树。

    参考代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 200005;
    
    long long a[N];
    long long sumv[N];
    int leftSon[N], rightSon[N];
    int cnt[N];
    
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
    
        int n;
        cin >> n;
    
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
        }
    
        for (int i = 1; i <= n; i++) {
            cin >> leftSon[i] >> rightSon[i];
        }
    
        vector<int> order;
        stack<int> st;
        st.push(1);
    
        while (!st.empty()) {
            int u = st.top();
            st.pop();
    
            order.push_back(u);
    
            if (leftSon[u] != 0) {
                st.push(leftSon[u]);
            }
            if (rightSon[u] != 0) {
                st.push(rightSon[u]);
            }
        }
    
        reverse(order.begin(), order.end());
    
        for (int u : order) {
            cnt[u] = 1;
            sumv[u] = a[u];
    
            if (leftSon[u] != 0) {
                cnt[u] += cnt[leftSon[u]];
                sumv[u] += sumv[leftSon[u]];
            }
    
            if (rightSon[u] != 0) {
                cnt[u] += cnt[rightSon[u]];
                sumv[u] += sumv[rightSon[u]];
            }
        }
    
        for (int i = 1; i <= n; i++) {
            cout << cnt[i] << " " << sumv[i] << "\n";
        }
    
        return 0;
    }
    
    • 1

    信息

    ID
    852
    时间
    1000ms
    内存
    512MiB
    难度
    普及−
    标签
    递交数
    0
    已通过
    0
    上传者