题目链接

题目

见链接。

题解

知识点: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;
}

CF383C Propagating tree的更多相关文章

  1. 「CF383C Propagating tree」

    这应该属于一个比较麻烦的数据结构处理树上问题. 题目大意 给出一颗根节点编号为 \(1\) 的树,对于一个节点修改时在它的子树中对于深度奇偶性相同的节点加上这个权值,不同则减去这个值,单点查询. 分析 ...

  2. CF383C Propagating tree (线段树,欧拉序)

    \(tag\)没开够\(WA\)了一发... 求出\(dfs\)序,然后按深度分类更新与查询. #include <iostream> #include <cstdio> #i ...

  3. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  4. Codeforces Round #225 (Div. 2) E. Propagating tree dfs序+-线段树

    题目链接:点击传送 E. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  5. AC日记——Propagating tree Codeforces 383c

    C. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. CodeForces 383C Propagating tree

    Propagating tree Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...

  7. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+ 树状数组或线段树

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  8. C. Propagating tree

    C. Propagating tree time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. 题解 CF383C 【Propagating tree】

    这道题明明没有省选难度啊,为什么就成紫题了QAQ 另:在CF上A了但是洛谷Remote Judge玄学爆零. 思路是DFS序+线段树. 首先这道题直观上可以对于每一次修改用DFS暴力O(n),然后对于 ...

  10. codeforces 383C Propagating tree 线段树

    http://codeforces.com/problemset/problem/383/C 题目就是说,  给一棵树,将一个节点的值+val, 那么它的子节点都会-val, 子节点的子节点+val. ...

随机推荐

  1. java 服务 JVM 参数设置配置

    本文为博主原创,转载请注明出处: 常用JVM 配置参数: -Xmx:表示java虚拟机堆区内存可被分配的最大上限,通常为操作系统可用内存的1/4大小. -Xms:表示java虚拟机堆区内存初始内存分配 ...

  2. 调整PR界面字体大小

    1.问题 界面字体太大或者太小,看得不舒服 2.解决问题 按住ctrl+F12,调出如下工作台 选择Debug Datatbase View 其中找到AdobeCleanFontSize,并修改 重启 ...

  3. [转帖]Oracle 23c 才支持 TLS1.3

    Transport Layer Security 1.3 Protocol Now Supported in Oracle Database Starting with Oracle Database ...

  4. [转帖]Shell 判断文件或文件夹是否存在(不存在则创建)

    目录 1. 文件夹不存在创建文件夹 2. 判断文件夹是否存在 3. 判断文件是否存在 4. 常用的文件比较符 1. 文件夹不存在创建文件夹 if [ ! -d "/data/" ] ...

  5. [转帖]通过拓扑 label 进行副本调度

    https://docs.pingcap.com/zh/tidb/stable/schedule-replicas-by-topology-labels#%E5%9F%BA%E4%BA%8E%E6%8 ...

  6. [转帖]为什么不推荐使用/etc/fstab

    https://www.jianshu.com/p/af49a5d0553f 对于工作中使用服务器的公司来讲,每到节假日来临时,总免不了对服务器进行下电.而收假回来的早上,则会有一个早上的时间会花费在 ...

  7. [转帖]在麒麟Linux安装Postgis

    https://jimolonely.github.io/tech/linux/install-postgis-kylin/ 接着上一篇在麒麟linux上安装Postgresql12.5 ,我们来安装 ...

  8. [转帖]ElasticSearch 最全详细使用教程

    https://zhuanlan.zhihu.com/p/449555826?utm_source=weibo&utm_medium=social&utm_oi=27124941455 ...

  9. grafana与K8S的下载地址

    https://grafana.com/grafana/download/9.1.6 https://dl.k8s.io/v1.15.1/kubernetes-node-linux-amd64.tar ...

  10. 源码学习之Spring容器创建原理

    1 前言 众所周知,Spring可以帮我们管理我们需要的bean.在我们需要用到这些bean的时候,可以很方便的获取到它,然后进行一系列的操作.比如,我们定义一个bean MyTestBean pub ...