首页 > 其他分享 >CF383C Propagating tree

CF383C Propagating tree

时间:2023-06-21 15:22:35浏览次数:44  
标签:val int void tree init dfn CF383C Propagating odd

题目链接

题目

见链接。

题解

知识点:DFS序,树状数组。

我们需要对子树的不同奇偶层加减,用dfn序可以解决子树问题,但是并不能直接分奇偶。

一种比较麻烦的思路是,将dfn序分成两个序列,一个是偶数层点序,一个是奇数层点序列,处理两个序列对于某个点作为子树根节点时,开始和结束节点,然后就可以用线段树分别处理差分。

但实际上,我们不需要对dfn序分离,只需要用两个完整的dfn序,分别统计对奇偶层的改变,每次修改同时修改两个序列的完整子树的差分,但加减不同即可。

其中,两个序列会出现不应该存在的点,比如对于统计偶数层的dfn序出现的奇数层点,那么直接对一个序列做完整子树的修改,会对它们产生错误的修改,但这是无关紧要的。因为我们查询的是单点权值,只要确定我们查询的那个点的奇偶性,去应该出现他的dfn序里查询即可,不存在的点是无法影响答案的。

如果问题改成求一个子树的权值和,那么这种方法就不行了,第一是没法方便的求出一个子树的权值和,因为奇偶层没有分离;第二是对不存在的点做了错误修改,只能用第一种麻烦的方法。

时间复杂度 \(O(n+m\log n)\)

空间复杂度 \(O(n)\)

代码

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

struct Graph {
    struct edge {
        int v, nxt;
    };
    int idx;
    vector<int> h;
    vector<edge> e;

    Graph(int n = 0, int m = 0) { init(n, m); }

    void init(int n, int m) {
        idx = 0;
        h.assign(n + 1, 0);
        e.assign(m + 1, {});
    }

    void add(int u, int v) {
        e[++idx] = { v,h[u] };
        h[u] = idx;
    }
};

struct T {
    int sum;
    static T e() { return { 0 }; }
    T &operator+=(const T &x) { return sum += x.sum, *this; }
};

template<class T>
struct Fenwick {
    int n;
    vector<T> node;

public:
    Fenwick(int _n = 0) { init(_n); }

    void init(int _n) {
        n = _n;
        node.assign(n + 1, T::e());
    }

    void update(int x, T val) { for (int i = x;i <= n;i += i & -i) node[i] += val; }

    T query(int x) {
        T ans = T::e();
        for (int i = x;i >= 1;i -= i & -i) ans += node[i];
        return ans;
    }
};

const int N = 200007;
Graph g;
int a[N];

int dfncnt;
int L[N], R[N], dep[N];
void dfs(int u, int fa) {
    L[u] = ++dfncnt;
    dep[u] = dep[fa] + 1;
    for (int i = g.h[u];i;i = g.e[i].nxt) {
        int v = g.e[i].v;
        if (v == fa) continue;
        dfs(v, u);
    }
    R[u] = dfncnt;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    g.init(n, n << 1);
    for (int i = 1;i <= n;i++) cin >> a[i];
    for (int i = 1;i <= n - 1;i++) {
        int u, v;
        cin >> u >> v;
        g.add(u, v);
        g.add(v, u);
    }
    dfs(1, 0);
    Fenwick<T> fw[2] = { Fenwick<T>(n),Fenwick<T>(n) };
    while (m--) {
        int op, x;
        cin >> op >> x;
        if (op == 1) {
            int val;
            cin >> val;
            bool odd = dep[x] & 1;
            fw[odd].update(L[x], { val });
            fw[odd].update(R[x] + 1, { -val });
            fw[odd ^ 1].update(L[x], { -val });
            fw[odd ^ 1].update(R[x] + 1, { val });
            //! 单点查询可以[L,R]区间加,因为不存在的点不会影响答案
            //! 但如果求子树权值和,那只能一开始就把dfs序按深度奇偶性分开,用线段树维护,操作很复杂
        }
        else cout << a[x] + fw[dep[x] & 1].query(L[x]).sum << '\n';
    }
    return 0;
}

标签:val,int,void,tree,init,dfn,CF383C,Propagating,odd
From: https://www.cnblogs.com/BlankYang/p/17496298.html

相关文章

  • 【vue3】实现el-tree组件
     禾小毅csdn博客【vue3】实现el-tree组件,将不同层级的箭头修改成自定义图标的组件封装及调用【vue3】实现简易的“百度网盘”文件夹的组件封装实现【vue3】实现公共搜索组件,在当前页搜索的路由跳转不能改变当前值的操作,使用bus/event-emitter派发器......
  • linux gpio dev,linux gpio子系统 devicetree中GPIO_ACTIVE_LOW
    一直没怎么理解GPIO_ACTIVE_LOW的作用对于以上的dts你应该再熟悉不过,当然这里不是教你如何使用dts,而是关注gpio和irq最后一个数字可以如何利用。例如rst-gpio的OF_GPIO_ACTIVE_LOW代表什么意思呢?可以理解为低有效。什么意思呢?举个例子,正常情况下,我们需要一个gpio口控制灯,我们认......
  • Vue3 element-Plus el-tree 权限树 传值给后端及回显问题
    内容:权限在新增人员时候选择传给后端并且编辑回显坑:1.传给后端的权限数组需要传父级id例如:一级目录下有二级目录和2-2目录,选了2-2目录,需要把一级目录的id也给后端2.回显的时候后端会把权限数组id都给你(包括一级目录),如果直接回显的话会默认一级下所有目录都选中 代......
  • TreeMap
    TreeMap的使用publicstaticvoidmain(String[]args){ TreeMap<String,Integer>map=newTreeMap<>(); //添加元素 Integerput1=map.put("大文",25); Integerput2=map.put("小文",26); Integerput3=map.put("小王",......
  • 哈夫曼树(Huffman Tree)的基本概念介绍
    哈夫曼树(HuffmanTree)是一种常用的数据结构,用于实现数据压缩和编码。它是由美国计算机科学家DavidA.Huffman于1952年提出的,被广泛应用于通信、压缩算法和信息存储等领域。哈夫曼树主要用于根据字符出现的频率构建最优的前缀编码,以便在压缩数据时能够有效地减少所需的比特数。该......
  • win10打开Sourcetree闪退解决方法
    前言昨天Sourcetree还可以正常使用,今天早上打开后出现下图就闪退了 百度尝试各种操作后找到解决方法,不知是否通用希望有人可以留言告知:删除掉:C:\Users\Administrator\AppData\Local\Atlassian目录下的如图文件,我是装在Administrator下面的,其他人按照实际位置删除 ......
  • element-tree相关经验汇总
    前言:这个el-tree是前段时间做项目时候写的,一直没时间进行整理,最近那个项目的tree数据超级大,导致浏览器卡死,需要进行处理,正好,趁着这次,把相关的配置也给整理一下(*^▽^*)大概呢就张这个样子:有查询、增加、删除、修改、上移、下移几个功能 那就先写一下相关配置吧: 我这个树上用......
  • 1483. Kth Ancestor of a Tree Node (Hard)
    Description1483.KthAncestorofaTreeNode(Hard)Youaregivenatreewithnnodesnumberedfrom0ton-1intheformofaparentarrayparentwhereparent[i]istheparentofithnode.Therootofthetreeisnode0.Findthekthancestorofagive......
  • odoo16里面修改tree视图样式
    一、在static文件夹下新建一个css文件夹并将*.css文件写入/*该文件用来定义视图中的一些格式,需要用到的地方直接在xml文件中进行引用*//*语法说明*//*tableth:nth-child(1)代表定位到table的th上面到第一个th标题nth-child()参考css语法http://www.w3school.com.cn/c......
  • TreeSet
    TreeSet的使用下面是TreeSet的方法使用,代码实现如下:publicstaticvoidmain(String[]args){ TreeSet<String>set=newTreeSet<>(); //添加元素 set.add("小希"); set.add("小空"); set.add("小丽"); set.add("小光"); //获取元素......