BZOJ3999 [TJOI2015]旅游
题面:给定一个有$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]旅游的更多相关文章
- BZOJ3999:[TJOI2015]旅游(树链剖分)
Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...
- BZOJ3999 [TJOI2015]旅游 【树剖 + 线段树】
题目 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会选择从A城市买入再 ...
- 2019.01.20 bzoj3999: [TJOI2015]旅游(树链剖分)
传送门 树链剖分菜题. 题意不清差评. 题意简述(保证清晰):给一棵带权的树,每次从aaa走到bbb,在走过的路径上任意找两个点,求后访问的点与先访问的点点权差的最大值. 思路: 考虑暴力:维护路径的 ...
- 【BZOJ3999】[TJOI2015]旅游(Link-Cut Tree)
[BZOJ3999][TJOI2015]旅游(Link-Cut Tree) 题面 BZOJ 洛谷 题解 一道不难的\(LCT\)题(用树链剖分不是为难自己吗,这种有方向的东西用\(LCT\)不是方便那 ...
- bzoj 3999: [TJOI2015]旅游
Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...
- [TJOI2015]旅游
树链剖分+线段树 线段树维护max,min,左往右的最大差,右往左的最大差 求LCA时一定要注意方向 # include <bits/stdc++.h> # define RG regis ...
- P3976 [TJOI2015]旅游(未完成)
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #inc ...
- bzoj 3999: [TJOI2015]旅游 LCT
没啥难的,inf 的值设小了调了半天~ code: #include <bits/stdc++.h> #define N 50003 #define lson t[x].ch[0] #de ...
- [暑假的bzoj刷水记录]
(这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊 堆一起算了 隔一段更新一下. 7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...
随机推荐
- FLASH CC 2015 CANVAS (六)如何像FLASH那样实现场景(多canvas)
注意 此系列贴 为个人边“开荒”边写,所以不保证就是最佳做法,也难免有错误! 正式教程会在后续开始更新. swf 项目中,我们可以很容易在一个fla文档里创建多场景.也可以通过多个fla文件发布多个s ...
- LINQ之路 2:C# 3.0的语言功能(上)
在上一篇的LINQ介绍中,我们已经看到了隐式类型变量var,扩展方法(extension method)和lambda表达式的身影.没错,他们正是LINQ技术的基石,是他们让LINQ的实现成为可能,并 ...
- 坐标随鼠标移动 jquery简易版
<html> <span style="position:absolute" id="xy_test"></span> &l ...
- 浅谈Android手机木马手工查杀
这篇文章主要是浅谈,所以会从简单方面开始讲起. 关于手机木马查杀,有些人会说安装手机杀毒软件不就解决了吗? 其实不然.因为手机和PC不一样,手机反木马技术没有PC端那么强. 就算你把目前市面上的所有手 ...
- Java初始化(成员变量)
java尽力保证:所有变量在使用前都能得到恰当的初始化.对于方法的局部变量,java以编译时错误的形式来贯彻这种保证.如下面代码: public class TestJava { void test( ...
- Python学习(13)函数
目录 Python 函数 函数调用 匿名函数 return语句 变量作用域 Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复 ...
- mysql 逻辑架构
1.mysql是基于网络的客户端/服务器架构,服务器上层是连接线程,解析器,查询缓存,下层是存储引擎. 2.每个客户端连接,服务器都有一个对应的线程,这个线程只为这个连接查询服务,高版本的mysql支 ...
- Java的加密与解密
package com.wangbo.util; import java.security.Key; import java.security.Security; import javax.crypt ...
- caffe的db_lmdb.hpp文件
先总的说一下: 类:LMDBCursor: 它干了点什么?它需要传入参数为:mdb_txn(传入它是因为用完它,把它absort掉), mdb_cursor;它应该是用来读出数据的: 类:LMDBT ...
- 转:C/C++中,空数组、空类、类中空数组的解析及其作用
转自:http://blog.sina.com.cn/s/blog_93b45b0f01015s95.html 我们经常会遇到这些问题: (1)C++中定义一个空类,他们它的大小(sizeof) 为多 ...