「TJOI2015」旅游

LCT沙比题

考虑我们其实是在维护一条链的\(\max\limits_{i<j} v_j-v_i\)

每次直接拿左右子树更新一下就可以了

写的时候把两个方向都维护一下,方便翻转


Code:

#include <cstdio>
#include <cctype>
#include <algorithm>
template <class T>
void read(T &x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
const int N=50010;
using std::min;
using std::max;
#define ls ch[now][0]
#define rs ch[now][1]
#define fa par[now]
int res[N],tag[N],ansl[N],ansr[N],ch[N][2],par[N],mx[N],mi[N],dat[N],s[N],tot;
int identity(int now){return ch[fa][1]==now;}
bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
void connect(int f,int now,int typ){ch[fa=f][typ]=now;}
void updata(int now)
{
ansl[now]=max(max(ansl[ls],ansl[rs]),max(mx[rs],dat[now])-min(mi[ls],dat[now]));
ansr[now]=max(max(ansr[ls],ansr[rs]),max(mx[ls],dat[now])-min(mi[rs],dat[now]));
mx[now]=max(max(mx[ls],mx[rs]),dat[now]);
mi[now]=min(min(mi[ls],mi[rs]),dat[now]);
}
void Reverse(int now)
{
res[now]^=1;
std::swap(ls,rs);
std::swap(ansl[now],ansr[now]);
}
void pushdown(int now)
{
if(tag[now])
{
if(ls) tag[ls]+=tag[now],mx[ls]+=tag[now],mi[ls]+=tag[now],dat[ls]+=tag[now];
if(rs) tag[rs]+=tag[now],mx[rs]+=tag[now],mi[rs]+=tag[now],dat[rs]+=tag[now];
tag[now]=0;
}
if(res[now])
{
if(ls) Reverse(ls);
if(rs) Reverse(rs);
res[now]=0;
}
}
void Rotate(int now)
{
int p=fa,typ=identity(now);
connect(p,ch[now][typ^1],typ);
if(isroot(p)) connect(par[p],now,identity(p));
else fa=par[p];
connect(now,p,typ^1);
updata(p),updata(now);
}
void splay(int now)
{
while(isroot(now)) s[++tot]=now,now=fa;
s[++tot]=now;
while(tot) pushdown(s[tot--]);
now=s[1];
for(;isroot(now);Rotate(now))
if(isroot(fa))
Rotate(identity(now)^identity(fa)?now:fa);
}
void access(int now)
{
for(int las=0;now;las=now,now=fa)
splay(now),rs=las,updata(now);
}
void evert(int now){access(now),splay(now),Reverse(now);}
void split(int u,int v)
{
evert(u);
access(v);
splay(v);
}
void modi(int now,int d){tag[now]+=d,dat[now]+=d,mx[now]+=d,mi[now]+=d;}
int query(int u,int v,int d)
{
split(u,v);
modi(v,d);
return ansl[v];
}
int head[N],to[N<<1],Next[N<<1],cnt;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
void dfs(int now)
{
for(int v,i=head[now];i;i=Next[i])
if((v=to[i])!=fa)
par[v]=now,dfs(v);
}
int main()
{
int n,q;
read(n);
mi[0]=1<<30;
for(int i=1;i<=n;i++) read(dat[i]),mx[i]=mi[i]=dat[i];
for(int u,v,i=1;i<n;i++) read(u),read(v),add(u,v),add(v,u);
dfs(1);
read(q);
for(int a,b,d,i=1;i<=q;i++)
{
read(a),read(b),read(d);
printf("%d\n",query(a,b,d));
}
return 0;
}

2019.2.24

「TJOI2015」旅游 解题报告的更多相关文章

  1. 「TJOI2015」概率论 解题报告

    「TJOI2015」概率论 令\(f_i\)代表\(i\)个点树形态数量,\(g_i\)代表\(i\)个点叶子个数 然后列一个dp \[ f_i=\sum_{j=0}^{i-1} f_j f_{i-j ...

  2. 「TJOI2015」组合数学 解题报告

    「TJOI2015」组合数学 这不是个贪心吗? 怎么都最小链覆盖=最大点独立集去了 注意到一个点出度最多只有2,可以贪心一下出度的去向 按读入顺序处理就可以,维护一个\(res_i\)数组,表示上一行 ...

  3. 「TJOI2015」线性代数 解题报告

    「TJOI2015」线性代数 和牛客某题很像 在和里面有\(B_{i,j}\)要求是\(A_i,A_j\)都为\(1\),和里面减去\(C_i\)要求\(A_i\)为\(1\),然后先把贡献也就是\( ...

  4. 「ZJOI2016」旅行者 解题报告

    「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...

  5. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

  6. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

  7. 「HNOI2016」网络 解题报告

    「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...

  8. 「HAOI2018」染色 解题报告

    「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...

  9. 「HNOI2016」最小公倍数 解题报告

    「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...

随机推荐

  1. 解决selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

    解决方案: 1.查看浏览器当前版本:chrome://version/. 2.到https://sites.google.com/a/chromium.org/chromedriver/downloa ...

  2. 配置nginx反向代理服务器,解决浏览器跨域调用接口的限制问题

    配置nginx反向代理服务器,解决浏览器跨域调用接口的限制问题 - 大venn的博客 - CSDN博客https://blog.csdn.net/u011135260/article/details/ ...

  3. Dockers 学习

    Docker镜像操作,有五个常用的命令: a.拉取镜像,后跟镜像仓库名称,如果要指定某个版本,可以带上tag. > docker pull <repo>[:tag] b.列出所有镜像 ...

  4. 转:MD5(Message-Digest Algorithm 一种哈希算法)

    什么是MD5算法 MD5讯息摘要演算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码杂凑函数,可以产生出一个128位元(16位元组)的散列值(hash val ...

  5. 动态SQL1

    If标签 动态SQL可以说是MyBatis最强大之处了,这块的应用主要有四个方面if,choose,trim和foreach,接下来先说说if. 顾名思义,if是用来判断条件的,现在假设我们有个需求, ...

  6. MyBatis源码分析1 参数映射分析

    首先我们拿出之前的代码,在如图位置打上断点,开始调试 我们规定了一个mapper接口,而调用了mapper接口的getEmpByIdAndLastName,我们并没有实现这个接口,这是因为Mybati ...

  7. python之路--触发器, 储存过程, 事务

    一. 触发器 使用触发器可以定制用户对某一张表的数据进行 [增, 删  ,改] 操作时前后的行为, (注意 没有查询),在进行增删改的时候出发的某个动作叫做 触发器. 其实就是在增删改的时候另外执行了 ...

  8. 如何在网页中用echarts图表插件做出静态呈现效果

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. LODOP中预览界面查看打印机的可打区域具体值

    LODOP在打印预览的时候,如果选择的打印机是真实打印机,会发现可能会有虚线,不同打印机虚线的位置不同,这个虚线是打印机的可打区域,Lodop无法控制. 可打区域,顾名思义,就是打印机可以打印的区域, ...

  10. orcale建表脚本

    declare v_cnt number; V_SQL VARCHAR2 (500) := '';begin select count(*) into v_cnt from dual where ex ...