HDU5692 Snacks(dfs序 + 线段树)
来源:互联网 发布:无法触碰 知乎 编辑:程序博客网 时间:2024/04/29 18:37
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5692
两场百度之星打的十分郁闷,但是也发现了我还是有很多的知识不能灵活运用,比如这题,dfs序我是懂的,线段树也是懂的,但是就是不知道怎么来做这题。
赛后看了takio菊苣的代码,觉得代码风格非常的清晰,很多地方加了空格以后看起来确实清楚很多。准备学习一下,虽然很影响手速,但是也慢慢改一改吧。
这题的思路实际上是这样的。先通过一次dfs来求得很多信息,比如dfs序,距离0点的距离,线段树中的下标代表的点。然后把距离0点的距离做成一棵线段树,这样的话,在x的子树的序列中,[L[x], R[x]]这段区间内,一定有0点到某个最远的点的距离,如果求出这个区间内的最大值,那么就是题目要求的最大距离。我们考虑修改操作,如果修改一个点的值的话,其实就是相当于修改整个子树的值,那么就用一个区间修改操作直接修改整个区间的值就好了。
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <iostream>#include <vector>#include <map>#include <set>#include <queue>#include <ctime>using namespace std;typedef long long ll;typedef pair<int,int> pii;#define pb push_back#define ls l, m#define rs m + 1, r#define lson l, m, rt << 1#define rson m + 1, r, rt << 1|1#define calm (l + r) >> 1const ll INF = 1e15;const int maxn = 100010;struct EE { int to, next; EE(){} EE(int to, int next):to(to), next(next){}}edge[maxn << 1];struct node { ll mx, tag;}tree[maxn << 2];int n, m, Case, Ecnt, tot;int head[maxn], L[maxn], R[maxn], rev[maxn];ll a[maxn], val[maxn];inline void add (int from, int to) { edge[Ecnt] = EE(to, head[from]); head[from] = Ecnt++;}void dfs (int s, int pre) { val[s] += val[pre]; L[s] = ++tot; rev[tot] = s; for (int i = head[s]; ~i; i = edge[i].next) { int t = edge[i].to; if (t == pre) continue; dfs (t, s); } R[s] = tot;}inline void pushup (int rt) { tree[rt].mx = max (tree[rt << 1].mx, tree[rt << 1 | 1].mx);}inline void pushdown (int rt) { if (tree[rt].tag) { tree[rt << 1].mx += tree[rt].tag; tree[rt << 1 | 1].mx += tree[rt].tag; tree[rt << 1].tag += tree[rt].tag; tree[rt << 1 | 1].tag += tree[rt].tag; tree[rt].tag = 0; }}void build (int l, int r, int rt) { tree[rt].tag = 0; if (l == r) { tree[rt].mx = val[rev[l]]; return; } int m = calm; build (lson); build (rson); pushup (rt);}void update (int L, int R, int c, int l, int r, int rt) { if (L <= l && r <= R) { tree[rt].mx += c; tree[rt].tag += c; return; } pushdown (rt); int m = calm; if (L <= m) update (L, R, c, lson); if (R > m) update (L, R, c, rson); pushup (rt);}ll query (int L, int R, int l, int r, int rt) { if (L <= l && r <= R) { return tree[rt].mx; } pushdown (rt); int m = calm; ll ans = -INF;//INF要设的大一点 if (L <= m) ans = query (L, R, lson); if (R > m) ans = max (ans, query (L, R, rson)); return ans;}int main() {// freopen ("D://input.txt", "r", stdin); int T; scanf ("%d", &T); while (T--) { printf ("Case #%d:\n", ++Case); scanf ("%d%d", &n, &m); memset (head, -1, sizeof head); Ecnt = 0; for (int i = 1; i < n; i++) { int x, y; scanf ("%d%d", &x, &y); ++x; ++y; add (x, y); add (y, x); } for (int i = 1; i <= n; i++) { scanf ("%I64d", &a[i]); val[i] = a[i]; } tot = 0; dfs (1, 0); build (1, n, 1); while (m--) { int op, x; scanf ("%d%d", &op, &x); ++x; if(!op) { int y; scanf ("%d", &y); update (L[x], R[x], y - a[x], 1, n, 1); a[x] = y; } else { printf ("%I64d\n", query (L[x], R[x], 1, n, 1)); } } } return 0;}
0 0
- HDU5692 Snacks(dfs序 + 线段树)
- HDU5692[Snacks]--DFS序+线段树
- HDU5692 Snacks DFS序 线段树
- hdu5692(dfs序+线段树 )Snacks
- hdu5692 Snacks(线段树+dfs序)
- HDU5692 Snacks (dfs序 + 线段树)
- HDU5692:Snacks(DFS序 & 线段树区间更新)
- HDU5692 Snacks【dfs序】
- HDU5692 线段树+dfs序
- hdu5692 (dfs序+线段树)
- HDU 5692 Snacks dfs序 + 线段树
- hdu 5692 Snacks(dfs序+线段树)
- HDU 5692 Snacks 【DFS序+线段树】
- 【hdu5692】Snacks
- HDU-5692-Snacks(DFS序+线段树)
- HDU 5692 Snacks( dfs序 + 线段树处理区间求和)
- hdu 5692 Snacks(dfs序+线段树)
- hdu 5692 Snacks(dfs序+线段树区间更新)
- java4
- ConvNetJS CIFAR-10 demo 卷积神经网络分类demo
- Android Studio代码着色插件
- java线程之间通讯
- Composer安装说明
- HDU5692 Snacks(dfs序 + 线段树)
- 使用eclipse开发servlet
- 浅谈Servlet的页面跳转
- [Android] CircleView 仿小米空气净化器首页旋转UI
- 博客评论时间显示算法
- [SCU 4509] Snowdrop修长廊 (斜率DP)
- web服务器 java实现
- OnPress长按事件
- LeetCode 133. Clone Graph(克隆图)