题目链接

题目

见链接。

题解

知识点: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. Spring Boot对接Oracle数据库

    Spring Boot对接Oracle数据库 最近学习了Oracle数据库,那么如何使用Spring Boot和MyBatis Plus对接Oracle数据库呢? 这就有了这篇随记,具体流程如下 1. ...

  2. 聊聊x86计算机启动发生的事?

    大家好,我是呼噜噜,最近在看linux早期内核0.12的源码,突然想到一个困扰自己好久的问题:当我们按下电源键,计算机发生了什么?神秘地址0x7C00究竟是什么?操作系统又是如何被加载到硬件中的?带着 ...

  3. scikit-learn.datasets 机器学习库

    scikit-learn是一个用于Python的机器学习库,提供了大量用于数据挖掘和数据分析的工具.以下是对这些函数和方法的简要描述: clear_data_home: 清除数据集目录的内容. dum ...

  4. [转帖]清除掉shared pool中某条sql语句方法

    https://www.xifenfei.com/2012/02/%E6%B8%85%E9%99%A4%E6%8E%89shared-pool%E4%B8%AD%E6%9F%90%E6%9D%A1sq ...

  5. [转帖]Intel固态硬盘总结

    https://www.cnblogs.com/hongdada/p/17326247.html 2012年推出的S3700,采用的是25nm闪存颗粒. 2015年推出s3710,采用的是20nm闪存 ...

  6. vCenter6.7 无法启动

    Get service 567f6edd-d4f7-4bfb-905b-1834c758a99d_com.vmware.vsphere.clientDon't update service 567f6 ...

  7. [转帖]nginx性能和软中断

    https://plantegg.github.io/2022/11/04/nginx%E6%80%A7%E8%83%BD%E5%92%8C%E8%BD%AF%E4%B8%AD%E6%96%AD/ n ...

  8. [转帖]SkyWalking集成logback

    1.引入skywalking的jar包,导入的包和agent版本一致 <dependency> <groupId>org.apache.skywalking</group ...

  9. [转帖]exec系统调用

    https://www.jianshu.com/p/3bf14f7d889c 进程的执行(exec) execve ececve系统调用可以将新程序加载到调用进程的内存空间,在这一过程中,将丢弃现有的 ...

  10. [转帖]计算机体系结构-cache高速缓存

    https://zhuanlan.zhihu.com/p/482651908 本文主要介绍了cache的基本常识.基本组成方式.写入方法和替换策略,在基本组成方式和替换策略两节给出了较为详细的硬件实现 ...