一 题目

  [HAOI2015]树上操作

二 分析

  树链剖分的题,这里主要用到了$dfs$序,这题比较简单的就是不用求$lca$。

  1.和树链剖分一样,先用邻接链表建双向图。

  2.跑两遍$dfs$,其实这题可以不这么写,主要是为了确定树型结构转线型后各节点的编号,以及各个链的$top$,$top$很关键,没有$top$就需要不断找父节点。

  3.建线段树,这里一定一定一定要仔细,写太丑就会调很久。o(╯□╰)o

  4.修改操作和常规线段树没有区别,但修改就需要对链上的$top$节点和父节点不断更新,知道找到根节点就可以了。

三 AC代码

  1 /**************************************************************
2 Problem: 4034
3 User: Dybala21
4 Language: C++
5 Result: Accepted
6 Time:2752 ms
7 Memory:16844 kb
8 ****************************************************************/
9
10 #include <bits/stdc++.h>
11 using namespace std;
12 #define ll long long
13
14 const int MAXN = 1e5 + 14;
15 int n, m;
16 int cost[MAXN];
17 int e[MAXN][2];
18 struct Edge
19 {
20 int to, next;
21 }edge[MAXN*2];
22 int head[MAXN], tot;
23 int fa[MAXN];
24 int p[MAXN];
25 int deep[MAXN];
26 int size[MAXN];
27 int son[MAXN];
28 int top[MAXN];
29 int pos;
30 void init()
31 {
32 tot = 0, pos = 0;
33 memset(head, -1, sizeof(head));
34 memset(son, -1, sizeof(son));
35 }
36 void addedge(int u, int v)
37 {
38 edge[tot].to = v;
39 edge[tot].next = head[u];
40 head[u] = tot++;
41 }
42 void dfs(int u, int pre, int d)
43 {
44 fa[u] = pre;
45 deep[u] = d;
46 size[u] = 1;
47 for(int i = head[u]; i != -1; i = edge[i].next)
48 {
49 int v = edge[i].to;
50 if(v != pre)
51 {
52 dfs(v, u, d+1);
53 size[u] += size[v];
54 if(son[u] == -1 || size[v] > size[son[u]])
55 son[u] = v;
56 }
57 }
58 }
59 void dfs2(int u, int sp)
60 {
61 top[u] = sp;
62
63 if(son[u] != -1)
64 {
65 p[u] = ++pos;
66 dfs2(son[u], sp);
67 }
68 else
69 {
70 p[u] = ++pos;
71 return;
72 }
73
74 for(int i = head[u]; i != -1; i = edge[i].next)
75 {
76 int v = edge[i].to;
77 if(v != son[u] && v != fa[u])
78 dfs2(v, v);
79 }
80 }
81 struct Node
82 {
83 int l, r;
84 ll sum, lazy;;
85 }segTree[MAXN*3];
86 void build(int rt, int l, int r)
87 {
88 segTree[rt].l = l;
89 segTree[rt].r = r;
90 segTree[rt].lazy = 0;
91 segTree[rt].sum = 0;
92 if(l == r)
93 return;
94 int mid = (l + r) >> 1;
95 build(rt<<1, l, mid);
96 build(rt<<1|1, mid + 1, r);
97 }
98 void pushdown(int rt)
99 {
100 if(segTree[rt].l == segTree[rt].r)
101 return;
102 int mid = (segTree[rt].l + segTree[rt].r)>>1;
103 ll t = segTree[rt].lazy;
104 segTree[rt].lazy = 0;
105 segTree[rt<<1].lazy += t;
106 segTree[rt<<1|1].lazy += t;
107 segTree[rt<<1].sum += t*(mid-segTree[rt].l+1);
108 segTree[rt<<1|1].sum += t*(segTree[rt].r-mid);
109 }
110 void update(int rt, int l, int r, ll val)
111 {
112 if(segTree[rt].lazy != 0)
113 pushdown(rt);
114 if(segTree[rt].l == l && segTree[rt].r == r)
115 {
116 segTree[rt].sum += (r-l+1)*val;
117 segTree[rt].lazy += val;
118 return;
119 }
120 int mid = (segTree[rt].l + segTree[rt].r)>>1;
121 if(r <= mid)
122 update(rt<<1, l, r, val);
123 else if(l > mid)
124 update(rt<<1|1, l, r, val);
125 else
126 {
127 update(rt<<1, l, mid, val);
128 update(rt<<1|1, mid + 1, r, val);
129 }
130 segTree[rt].sum = segTree[rt<<1].sum + segTree[rt<<1|1].sum;
131 }
132 ll query(int rt, int l, int r)
133 {
134 if(segTree[rt].lazy)
135 pushdown(rt);
136 if(segTree[rt].l == l && segTree[rt].r == r)
137 return segTree[rt].sum;
138 int mid = (segTree[rt].l + segTree[rt].r)>>1;
139 if(r <= mid)
140 return query(rt<<1, l, r);
141 else if(l > mid)
142 return query(rt<<1|1, l, r);
143 else
144 {
145 ll res = 0;
146 res += query(rt<<1, l, mid);
147 res += query(rt<<1|1, mid+1, r);
148 return res;
149 }
150 }
151 ll query(int x)
152 {
153 ll ans = 0;
154 while(top[x] != 1)
155 {
156 ans += query(1, p[top[x]], p[x]);
157 x = fa[top[x]];
158 }
159 ans += query(1, 1, p[x]);
160 return ans;
161 }
162 int main()
163 {
164 //freopen("in.txt", "r", stdin);
165 //freopen("out.txt", "w", stdout);
166 init();
167 scanf("%d%d", &n, &m);
168 for(int i = 1; i <= n; i++)
169 {
170 scanf("%d", &cost[i]);
171 }
172 for(int i = 0; i < n-1; i++)
173 {
174 scanf("%d%d", &e[i][0], &e[i][1]);
175 addedge(e[i][0], e[i][1]);
176 addedge(e[i][1], e[i][0]);
177 }
178 dfs(1, 0, 0);
179 dfs2(1, 1);
180 build(1, 1, pos);
181 for(int i = 1; i <= n; i++)
182 update(1, p[i], p[i], cost[i]);
183 int op, x, xa;
184 for(int i = 0; i < m; i++)
185 {
186 scanf("%d", &op);
187 if(op == 1)
188 {
189 scanf("%d%d", &x, &xa);
190 update(1, p[x], p[x], xa);
191 }
192 else if(op == 2)
193 {
194 scanf("%d%d", &x, &xa);
195 update(1, p[x], p[x] + size[x] - 1, xa);
196 }
197 else
198 {
199 scanf("%d", &x);
200 printf("%lld\n", query(x) );
201 }
202 }
203 return 0;
204 }
205

BZOJ_4034 [HAOI2015]树上操作 【树链剖分dfs序+线段树】的更多相关文章

  1. BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)

    题目链接 设白色结点为未安装的软件,黑色结点为已安装的软件,则: 安装软件i:输出结点i到根的路径上的白色结点的数量,并把结点i到根的路径染成黑色.复杂度$O(nlog^2n)$ 卸载软件i:输出结点 ...

  2. bzoj 4034 [HAOI2015]树上操作 入栈出栈序+线段树 / 树剖 维护到根距离和

    题目大意 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...

  3. BZOJ 2286 树链剖分+DFS序+虚树+树形DP

    第一次学习虚树,就是把无关的点去掉.S里维护一条链即可. #include <iostream> #include <cstring> #include <cstdio& ...

  4. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

  5. BZOJ 2243:染色(树链剖分+区间合并线段树)

    [SDOI2011]染色Description给定一棵有n个节点的无根树和m个操作,操作有2类:1.将节点a到节点b路径上所有点都染成颜色c:2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认 ...

  6. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  7. [BZOJ - 2819] Nim 【树链剖分 / DFS序】

    题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...

  8. POJ 2763 Housewife Wind 【树链剖分】+【线段树】

    <题目链接> 题目大意: 给定一棵无向树,这棵树的有边权,这棵树的边的序号完全由输入边的序号决定.给你一个人的起点,进行两次操作: 一:该人从起点走到指定点,问你这段路径的边权总和是多少. ...

  9. 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树

    题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...

随机推荐

  1. Java RMI 实现一个简单的GFS(谷歌文件系统)——背景与设计篇

    目录 背景 系统设计 1. 系统功能 2. Master组件 2.1 命名空间 2.2 心跳机制 2.3 故障恢复和容错机制 3. ChunkServer组件 3.1 本地存储 3.2 内存命中机制 ...

  2. redis跳表

    redis使用跳表作为有序集合的底层实现之一,下面来看下跳表的结构 一.跳表的结构

  3. Github App version released icons

    # Github App version released icons http://shields.io/ Build Travis: https://img.shields.io/travis/U ...

  4. free online markdown editor

    free online markdown editor markdown https://blog.csdn.net/xgqfrms/article/details/50129317 In-brows ...

  5. js & void() & void(0)

    js & void() & void(0) https://www.runoob.com/js/js-void.html void() <a href="javascr ...

  6. window.locationbar

    window.locationbar demo https://cdn.xgqfrms.xyz/#/operate-tool/select-seat-system/select-detail?temp ...

  7. 投资者通过这几种方式可以快速在NGK赚取收益

    2020年全球经济危机,各国经济持续低迷,资本市场变得躁动不安.而区块链市场,却异常火爆.各种公链项目相继而起,DeFi.分布式存储一个比一个火爆.NGK公链,无疑成为了这场热潮中有力的推动者之一,一 ...

  8. Windows Server2012 r2 nginx反向代理图片服务器

    1.下载nginx  http://nginx.org/en/download.html,本人下载的1.18.0版本 2.下载 Windows Service Wrapper(winsw.exe) v ...

  9. JQuery:JQuery基本语法,JQuery选择器,JQuery DOM,综合案例 复选框,综合案例 随机图片

    知识点梳理 课堂讲义 1.JQuery快速入门 1.1.JQuery介绍 jQuery 是一个 JavaScript 库. 框架:Mybatis (jar包) 大工具 插件:PageHelper (j ...

  10. E百科 | 基于MEC的边缘AI服务

    简介: 阿里云边缘计算团队付哲解读5G下热门场景:边缘AI.作者:阿里云付哲,计算机科学与技术专业博士后,在流量检测.资源调度领域有深入研究,其论文<Astraea: Deploy AI Ser ...