题面:给定一个有$n$个节点的树,每个点又点权$v_i$,每次选取一条树链$[a, b]$,求出$max(v_i - v_j)$,其中$i, j \in [a, b]$且$i$出现在$j$前面,最后树链$[a, b]$上的点点权都加上$v'$

裸的树链剖分,用线段树维护树链。。。查询的时候要用线段树合并。。。然后就没有然后了。。。

代码能力捉鸡QAQQQ,而且貌似是C++程序里面跑的最慢的QAQQQ

 /**************************************************************
Problem: 3999
User: rausen
Language: C++
Result: Accepted
Time:4268 ms
Memory:17988 kb
****************************************************************/ #include <cstdio>
#include <algorithm> using namespace std;
typedef long long ll;
const int N = 5e4 + ;
const int inf = 1e9; inline int read(); int n;
int a[N], seq[N], cnt_seq; struct edge {
int next, to;
edge() {}
edge(int _n, int _t) : next(_n), to(_t) {}
} e[N << ]; int first[N], tot; struct tree_node {
int sz, dep, fa, son, v;
int top, pos;
} tr[N]; struct seg {
seg *ls, *rs, *res;
ll mx, mn, mxl, mxr, tag; #define Len (1 << 16)
inline void* operator new(size_t) {
static seg *mempool, *c;
if (mempool == c)
mempool = (c = new seg[Len]) + Len;
return c++;
}
#undef Len
inline seg& operator += (int x) {
mx += x, mn += x, tag += x;
} inline seg* rev() {
swap(mxl, mxr);
return this;
}
inline void update(seg *ls, seg *rs) {
mxl = max(max(ls -> mxl, rs -> mxl), ls -> mx - rs -> mn);
mxr = max(max(ls -> mxr, rs -> mxr), rs -> mx - ls -> mn);
mx = max(ls -> mx, rs -> mx), mn = min(ls -> mn, rs -> mn);
}
inline void push() {
if (tag) {
*ls += tag, *rs += tag;
tag = ;
}
} #define mid (l + r >> 1)
inline void build(int l, int r, int* a) {
res = new()seg;
if (l == r) {
mx = mn = a[l];
return;
}
ls = new()seg(), rs = new()seg;
ls -> build(l, mid, a), rs -> build(mid + , r, a);
update(ls, rs);
} inline void add(int l, int r, int L, int R, int d) {
if (L <= l && r <= R) {
*this += d;
return;
}
push();
if (L <= mid) ls -> add(l, mid, L, R, d);
if (mid < R) rs -> add(mid + , r, L, R, d);
update(ls, rs);
} inline seg* query(int l, int r, int L, int R) {
if (L <= l && r <= R) {
*res = *this;
return res;
}
*res = seg(), push();
if (mid >= R) res = ls -> query(l, mid, L, R);
else if (mid < L) res = rs -> query(mid + , r, L, R);
else res -> update(ls -> query(l, mid, L, R), rs -> query(mid + , r, L, R));
update(ls, rs);
return res;
}
#undef mid
} *T; inline void get(seg *t, int f, int a, int b, int v) {
if (!f) t -> update(T -> query(, n, a, b), t);
else t -> update(t, T -> query(, n, a, b) -> rev());
T -> add(, n, a, b, v);
} inline void pre(seg *t) {
*t = seg();
t -> mx = t -> mxl = t -> mxr = -inf, t -> mn = inf;
} inline void work(int x, int y, int v) {
static seg *left = new()seg, *right = new()seg, *ans = new()seg;
pre(left), pre(right);
while (tr[x].top != tr[y].top) {
if (tr[tr[x].top].dep > tr[tr[y].top].dep)
get(right, , tr[tr[x].top].pos, tr[x].pos, v), x = tr[tr[x].top].fa;
else
get(left, , tr[tr[y].top].pos, tr[y].pos, v), y = tr[tr[y].top].fa;
}
if (tr[x].dep > tr[y].dep) get(right, , tr[y].pos, tr[x].pos, v);
else get(left, , tr[x].pos, tr[y].pos, v);
ans -> update(left, right);
printf("%lld\n", max(ans -> mxl, 0ll));
} inline void Add_Edges(int x, int y) {
e[++tot] = edge(first[x], y), first[x] = tot;
e[++tot] = edge(first[y], x), first[y] = tot;
} #define y e[x].to
void dfs(int p) {
int x;
tr[p].sz = ;
for (x = first[p]; x; x = e[x].next)
if (y != tr[p].fa) {
tr[y].fa = p, tr[y].dep = tr[p].dep + ;
dfs(y);
tr[p].sz += tr[y].sz;
if (!tr[p].son || tr[tr[p].son].sz < tr[y].sz) tr[p].son = y;
}
} void DFS(int p) {
int x;
seq[tr[p].pos = ++cnt_seq] = tr[p].v;
if (!tr[p].son) return;
tr[tr[p].son].top = tr[p].top;
DFS(tr[p].son);
for (x = first[p]; x; x = e[x].next)
if (y != tr[p].fa && y != tr[p].son)
tr[y].top = y, DFS(y);
}
#undef y int main() {
int i, x, y, z, Q;
n = read();
for (i = ; i <= n; ++i) tr[i].v = read();
for (i = ; i < n; ++i)
Add_Edges(read(), read());
dfs();
tr[].top = , DFS();
T = new()seg;
T -> build(, n, seq);
for (Q = read(); Q; --Q) {
x = read(), y = read(), z = read();
work(x, y, z);
}
return ;
} inline int read() {
static int x;
static char ch;
x = , ch = getchar();
while (ch < '' || '' < ch)
ch = getchar();
while ('' <= ch && ch <= '') {
x = x * + ch - '';
ch = getchar();
}
return x;
}

BZOJ3999 [TJOI2015]旅游的更多相关文章

  1. BZOJ3999:[TJOI2015]旅游(树链剖分)

    Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...

  2. BZOJ3999 [TJOI2015]旅游 【树剖 + 线段树】

    题目 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会选择从A城市买入再 ...

  3. 2019.01.20 bzoj3999: [TJOI2015]旅游(树链剖分)

    传送门 树链剖分菜题. 题意不清差评. 题意简述(保证清晰):给一棵带权的树,每次从aaa走到bbb,在走过的路径上任意找两个点,求后访问的点与先访问的点点权差的最大值. 思路: 考虑暴力:维护路径的 ...

  4. 【BZOJ3999】[TJOI2015]旅游(Link-Cut Tree)

    [BZOJ3999][TJOI2015]旅游(Link-Cut Tree) 题面 BZOJ 洛谷 题解 一道不难的\(LCT\)题(用树链剖分不是为难自己吗,这种有方向的东西用\(LCT\)不是方便那 ...

  5. bzoj 3999: [TJOI2015]旅游

    Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...

  6. [TJOI2015]旅游

    树链剖分+线段树 线段树维护max,min,左往右的最大差,右往左的最大差 求LCA时一定要注意方向 # include <bits/stdc++.h> # define RG regis ...

  7. P3976 [TJOI2015]旅游(未完成)

    #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #inc ...

  8. bzoj 3999: [TJOI2015]旅游 LCT

    没啥难的,inf 的值设小了调了半天~ code: #include <bits/stdc++.h> #define N 50003 #define lson t[x].ch[0] #de ...

  9. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

随机推荐

  1. C++ Redis mset 二进制数据接口封装方案

    C++ Redis mset 二进制数据接口封装方案 需求 C++中使用hiredis客户端接口访问redis: 需要使用mset一次设置多个二进制数据 以下给出三种封装实现方案: 简单拼接方案 在r ...

  2. Win7路由器设置过程

    随着应用win7系统的人越来越多,对于这个系统的应用就更多了,其中大家最关注的就是这个系统和路由器上网的问题.下面,我们就来讲解一下win7系统的路由器的设置过程. 首先打开浏览器,在地址栏输入192 ...

  3. XP_版本

    1. Windows XP sp3 cd 和Windows XP sp3 cd vl的区别?VL的意思是大客户版,就是使用VL的KEY安装的系统是不需要激活的,不带VL的是安装完后需要激活的零售版 2 ...

  4. OC拓展(category)

    1. 扩展类的功能Category提供了一种比继承(inheritance)更为简洁的方法来对class进行扩展,我们可以为任何已经存在的class添加方法(不包括数据成员)却不需要访问该class的 ...

  5. [转载] Linux下高并发socket最大连接数所受的各种限制

    原文: http://mp.weixin.qq.com/s?__biz=MzAwNjMxNjQzNA==&mid=207772333&idx=1&sn=cfc8aadb422f ...

  6. 学习笔记day6:position index结合

    z-index属性适用于定位元素(position 属性值为 relative 或 absolute 或 fixed的对象),用来确定定位元素在垂直于显示屏方向(称为Z轴)上的层叠顺序(stack o ...

  7. 07 SQL优化技术

    本章提要------------------------------------------------------调优技术及什么时候使用------------------------------- ...

  8. vim的配置文件及常用的快捷键

    一些最简单的配置,即在.vimrc中可以写入的配置: 首先,说明一点,在.vimrc文件中,可以用“  把一行的配置注销掉. set nocompatible  “关闭 vi 兼容模式:其中 comp ...

  9. Android的启动模式(上)

    1. 基本介绍 大家平时只要懂一点Android知识的话,都一定会知道,一个应用的组成,往往包含了许多的activity组件,每个activity都应该围绕用户的特定动作进行跳转设计.比如说,一个电话 ...

  10. [css] vertical-align和line-height

    原文链接:http://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-height/ ...