题面:给定一个有$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. Codeforces Round #376 (Div. 2) F. Video Cards 数学,前缀和

    F. Video Cards time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  2. uploads 上传图片

    public static function upFile($r,$p='../images/link/',$type='gif,jpg,png',$named=0){ $newnames = nul ...

  3. nodejs学习笔记<四>处理请求参数

    在web开发中处理请求参数是个非常常见的工作:nodejs提供了了querystring用来处理请求参数. querystring常用方法有:parse,stringify. (1)parse: 解析 ...

  4. SQLserver批量删除空表

    今天需要清理一个很大的数据库,里面表有一堆,而且有很多是空表.想着把数据库弄小点,于是想到一次性删掉所有空表. 废话不多说,上代码. 首先,查处所有的空表. select distinct a.nam ...

  5. iOS开发之如何修改Mac截屏保存路径

    如何修改Mac截屏保存路径   MAC OS X系统默认的截图路径是桌面文件夹,默认的截图格式是 PNG 图片格式,如何自定义设置呢? 截图保存路径 打开终端(Terminal)并输入如下命令: de ...

  6. ctrl+enter提交留言

    <!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8&qu ...

  7. linux特殊字符

    linux特殊字符: * 匹配文件名中的任何字符串,包括空字符串. ? 匹配文件名中的任何单个字符. [...] 匹配[ ]中所包含的任何字符. [!...] 匹配[ ]中非感叹号!之后的字符. 当s ...

  8. Mybatis3+Spring4+SpringMVC4 整合

    首先在整合这个框架的时候,想想其一般的步骤是怎样的,先有个步骤之后,不至于在后面的搞混了,这样在整合的时候也比较清晰些. 然后我们就细细的一步一步来整合. 1  创建一个Web项目. 2  导入Myb ...

  9. 删除github账号的方法

    如果你不想使用自己的github账号了,github官网允许你删除账号,具体操作步骤为: 1.登录github网站,网站右上角的头像,在下拉菜单中选择"Settings"(设置): ...

  10. 转!!Java学习之自动装箱和自动拆箱源码分析

    自动装箱(boxing)和自动拆箱(unboxing)   首先了解下Java的四类八种基本数据类型   基本类型 占用空间(Byte) 表示范围 包装器类型 boolean 1/8 true|fal ...