Description

给定一棵有根树,每次操作一个结点(将它加上 \(v\),孩子减去 \(v\),孩子的孩子加上 \(v\),以此类推),或者查询一个结点的值。

Solution

考虑维护两个序列,一个序列中所有深度为奇数的点是有效的,另一个序列中所有深度为偶数的点是有效的。如果操作的一个点是奇数深度的,那么就在前者中加,后者中减,若是偶数深度则恰好相反。当我们取出一个点的权值的时候,根据它是奇数深度的点还是偶数深度的点到对应的序列中取即可。

通过 DFS 序转化为区间操作单点询问,再通过差分转化为单点修改区间询问,于是用树状数组处理即可。

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 1000005;

struct BIT
{
    vector<int> a;
    int size;
    BIT(int size) : size(size)
    {
        a.resize(size + 2);
    }
    int lowbit(int i)
    {
        return i & (-i);
    }
    void add(int i, int v)
    {
        while (i <= size)
        {
            a[i] += v;
            i += lowbit(i);
        }
    }
    int sum(int i)
    {
        int ans = 0;
        while (i > 0)
        {
            ans += a[i];
            i -= lowbit(i);
        }
        return ans;
    }

    void Modify(int l, int r, int v)
    {
        add(l, v);
        add(r + 1, -v);
    }

    int Query(int r)
    {
        return sum(r);
    }
};

vector<int> g[N];
int dep[N], vis[N], dfn[N], fin[N], ind;

void dfs(int p)
{
    dfn[p] = ++ind;
    vis[p] = 1;
    for (int q : g[p])
    {
        if (vis[q] == 0)
        {
            dep[q] = dep[p] + 1;
            dfs(q);
        }
    }
    fin[p] = ind;
}

signed main()
{
    int n, m;
    cin >> n >> m;

    BIT *bit[2];
    bit[0] = new BIT(n);
    bit[1] = new BIT(n);

    vector<int> a(n + 2);
    for (int i = 1; i <= n; i++)
        cin >> a[i];

    for (int i = 1; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    dfs(1);

    for (int i = 1; i <= n; i++)
    {
        bit[0]->Modify(dfn[i], dfn[i], a[i]);
        bit[1]->Modify(dfn[i], dfn[i], a[i]);
    }

    for (int i = 1; i <= m; i++)
    {
        int t1, t2, t3;
        cin >> t1 >> t2;
        if (t1 == 1)
        {
            cin >> t3;
            bit[dep[t2] & 1]->Modify(dfn[t2], fin[t2], t3);
            bit[(dep[t2] & 1) ^ 1]->Modify(dfn[t2], fin[t2], -t3);
        }
        else
        {
            cout << bit[dep[t2] & 1]->Query(dfn[t2]) << endl;
        }
    }
}

相关文章:

  • 2021-05-27
  • 2022-01-16
  • 2021-05-29
  • 2022-12-23
  • 2021-06-14
  • 2021-11-24
  • 2022-12-23
  • 2021-11-04
猜你喜欢
  • 2021-08-05
  • 2021-06-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案