【树链剖分】旅游(luogu 3976)

正题

luogu 3976


题目大意

给你一棵树,每个点有一个权值s

现在给你一条路径,让你选择两个点x,y,使y在x后面,且sy−sxs_y-s_xsysx最大

然后该路劲上所有点权值加v


解题思路

树链剖分

在线段树上维护从左到右和从右到左的最大价值

每次查询,如果是跳开头就找最小的,如果是跳结尾就找最大的


代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 500100
using namespace std;
int n, x, y, z, w, m, tot;
int s[N], v[N], ww[N], fa[N], fv[N], hs[N], dep[N], anc[N], head[N];
struct rec
{int to, next;
}a[N<<1];
struct node
{int mn, mx, ml, mr;
};
struct Tree
{int mx[N<<2], mn[N<<2], ml[N<<2], mr[N<<2], lazy[N<<2];#define ls x*2#define rs x*2+1void addd(int x, int y){lazy[x] += y;mn[x] += y;mx[x] += y;}void down(int x){if (lazy[x]){addd(ls, lazy[x]);addd(rs, lazy[x]);lazy[x] = 0;}return;}void up(int x){mn[x] = min(mn[ls], mn[rs]);mx[x] = max(mx[ls], mx[rs]);ml[x] = max(mx[rs] - mn[ls], max(ml[ls], ml[rs]));//从左到右和从右到左的最大价值mr[x] = max(mx[ls] - mn[rs], max(mr[ls], mr[rs]));}void build(int x, int l, int r){if (l == r){mn[x] = mx[x] = ww[fv[l]];return;}int mid = l + r >> 1;build(ls, l, mid);build(rs, mid + 1, r);up(x); return;}void add(int x, int L, int R, int l, int r, int y){if (L == l && R == r){addd(x, y);return;}int mid = L + R >> 1;down(x);if (r <= mid) add(ls, L, mid, l, r, y);else if (l > mid) add(rs, mid + 1, R, l, r, y);else add(ls, L, mid, l, mid, y), add(rs, mid + 1, R, mid + 1, r, y);up(x);return;}node ask(int x, int L, int R, int l, int r)//查询区间的各个值{if (L == l && R == r) return (node){mn[x], mx[x], ml[x], mr[x]};int mid = L + R >> 1;down(x);if (r <= mid) return ask(ls, L, mid, l, r);else if (l > mid) return ask(rs, mid + 1, R, l, r);else{node x1 = ask(ls, L, mid, l, mid);node x2 = ask(rs, mid + 1, R, mid + 1, r);node x3;x3.mn = min(x1.mn, x2.mn);x3.mx = max(x1.mx, x2.mx);x3.ml = max(max(x1.ml, x2.ml), x2.mx - x1.mn);x3.mr = max(max(x1.mr, x2.mr), x1.mx - x2.mn);return x3;}}
}T;
void add(int x, int y)
{a[++tot].to = y;a[tot].next = head[x];head[x] = tot;
}
void dfs1(int x)
{s[x] = 1;for (int i = head[x]; i; i = a[i].next)if (a[i].to != fa[x]){fa[a[i].to] = x;dep[a[i].to] = dep[x] + 1;dfs1(a[i].to);s[x] += s[a[i].to];if (s[a[i].to] > s[hs[x]]) hs[x] = a[i].to;}return;
}
void dfs2(int x, int y)
{anc[x] = y;v[x] = ++w;fv[w] = x;if (hs[x]) dfs2(hs[x], y);for (int i = head[x]; i; i = a[i].next)if (a[i].to != fa[x] && a[i].to != hs[x])dfs2(a[i].to, a[i].to);return;
}
void solve(int x, int y, int z)
{int fx = anc[x], fy = anc[y];while (fx != fy){if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);T.add(1, 1, n, v[fx], v[x], z);x = fa[fx];fx = anc[x];}if (dep[x] > dep[y]) swap(x, y);T.add(1, 1, n, v[x], v[y], z);return;
}
int ask(int x, int y)
{int fx = anc[x], fy = anc[y], bg = 1000000000, ed = 0, ans = 0;while (fx != fy){if (dep[fx] > dep[fy]){node x1 = T.ask(1, 1, n, v[fx], v[x]);ans = max(ans, max(x1.mr, x1.mx - bg));//计算结果bg = min(bg, x1.mn);//最小的x = fa[fx];fx = anc[x];}else{node x1 = T.ask(1, 1, n, v[fy], v[y]);ans = max(ans, max(x1.ml, ed - x1.mn));ed = max(ed, x1.mx);y = fa[fy];fy = anc[y];}}if (dep[x] > dep[y]){node x1 = T.ask(1, 1, n, v[y], v[x]);ans = max(ans, max(x1.mr, x1.mx - bg));bg = min(bg, x1.mn);}else{node x1 = T.ask(1, 1, n, v[x], v[y]);ans = max(ans, max(x1.ml, ed - x1.mn));ed = max(ed, x1.mx);}return max(ed - bg, ans);
}
int main()
{scanf("%d", &n);for (int i = 1; i <= n; ++i)scanf("%d", &ww[i]);for (int i = 1; i < n; ++i){scanf("%d%d", &x, &y);add(x, y);add(y, x);}dep[1] = fa[1] = 1;dfs1(1);dfs2(1, 1);T.build(1, 1, n);scanf("%d", &m);for (int i = 1; i <= m; ++i){scanf("%d%d%d", &x, &y, &z);printf("%d\n", ask(x, y));solve(x, y, z);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P7276-送给好友的礼物【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P7276?contestId39577 题目大意 nnn个点的一棵树&#xff0c;kkk个关键点&#xff0c;两个人从根出发分别走一段路径回到根。要求每个关键点至少被一个人经过&#xff0c;求最短时间。 解题思路 相当于求两个覆盖所有关键点…

dump文件解析之探索.Net的内存

前言&#xff1a;对于需要长时间运行的.net程序&#xff0c;有时需要我们查看内存的使用有没有内存泄露问题。我们可以从dump文件中找到答案。Dump的看点用dump文件来分析内存&#xff0c;到底我们需要关心哪些点呢&#xff1f;内存的使用情况 HeapSize/object的数量 也就是托管…

Codeforces Round #654 (Div. 2)

A.Magical Sticks 贪心凑长度为nnn的木棒 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> using namespace std; int n; int main() {IO;int T;cin>>T;while(T--){cin>>n;cout<<(n1)/…

P3307-[SDOI2013]项链【Burnside引理,莫比乌斯反演,特征方程】

正题 题目链接:https://www.luogu.com.cn/problem/P3307 题目大意 nnn个珠子的一个环形项链&#xff0c;每个珠子有三个1∼k1\sim k1∼k的整数。 两个珠子不同当且仅当它们不能通过翻转或者旋转得到两个项链不同当且仅当它们不能通过旋转得到珠子要求上面的数字互质项链要求相…

【树链剖分】Milk Visits G(luogu 5838)

正题 luogu 5838 题目大意 给你一棵树&#xff0c;和若干查询&#xff0c;每次查询一条路径上是否有点的权值为x 解题思路 离线处理&#xff0c;每次将树上权值为x的点附上1的值&#xff0c;然后询问就是求和&#xff0c;查询完后清零 代码 #include<cstdio> #includ…

2020牛客暑期多校训练营(第二场)

2020牛客暑期多校训练营&#xff08;第二场&#xff09; 最烦英语题 文章目录A All with PairsB BoundaryC Cover the TreeD DurationE Exclusive ORF Fake MaxpoolingG Greater and GreaterH Happy TriangleI IntervalJ Just ShuffleK Keyboard FreeA All with Pairs B Bound…

鸿蒙 - arkTs:状态管理

状态 State&#xff1a; 在声明式UI中&#xff0c;以状态驱动视图更新 状态&#xff08;State&#xff09;&#xff1a;指驱动视图更新的数据&#xff08;被装饰器标记的变量&#xff09;视图&#xff08;View&#xff09;&#xff1a;基于UI描述渲染得到的用户界面 使用示例…

微软发布Azure Pipelines,开源项目可无限制使用CI/CD

微软发布了Azure Pipelines&#xff0c;他们新的CI/CD服务&#xff0c;是Azure DevOps产品的一部分。Azure Pipelines可用于构建、测试和部署工作负载&#xff0c;并可以让各种语言、项目类型和平台协同工作。作为Visual Studio Team Services&#xff08;VSTS&#xff09;的后…

Codeforces Round #653 (Div. 3)

A.Required Remainder 二分 #include<iostream> #include<algorithm> using namespace std; int main() {int T;ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>T;int x,y,n;while(T--){cin>>x>>y>>n;int l0,r(n-y)/x;while(…

【树链剖分】【倍增】宝石(2021GDOI Day2 T1)

正题 luogu 7518 题目大意 给你一棵树&#xff0c;一条路径的价值为&#xff1a;路径上点权以1开始依次递增1的子序列&#xff0c;有q次询问&#xff0c;每次询问一条路径的价值 解题思路 n,m值比较大&#xff0c;对于每次询问只有O(log2n)O(log^2n)O(log2n)的时间 考虑树链…

2020牛客暑期多校训练营(第一场)

文章目录A B-Suffix ArrayB Infinite TreeC DominoD Quadratic FormE Counting Spanning TreesF Infinite String Comparision题意&#xff1a;题解&#xff1a;代码&#xff1a;G BaXianGuoHai, GeXianShenTongH Minimum-cost FlowI 1 or 2J Easy Integration题意题解代码2020…

P4755-Beautiful Pair【笛卡尔树,线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P4755 题目大意 nnn个数字的一个序列&#xff0c;求有多少个点对i,ji,ji,j满足aiaj≤max{ak}(k∈[l,r])a_i\times a_j\leq max\{a_k\}(k\in[l,r])ai​aj​≤max{ak​}(k∈[l,r]) 解题思路 如果构建一棵笛卡尔树的话那么两个点…

C# 接受MQTT服务器推送的消息

前言&#xff1a;MQTT是IBM开发的一个即时通讯协议。MQTT是面向M2M和物联网的连接协议&#xff0c;采用轻量级发布和订阅消息传输机制。大家可以直接上GitHub下载MQQT服务的源码&#xff0c;源码地址&#xff1a;https://github.com/mqtt/mqtt.github.io/wiki/libraries主要内容…

【堆】【DP】Niyaz and Small Degrees(luogu 7600[APIO 2021 T3]/luogu-CF1119F)

正题 luogu 7600[APIO 2021 T3] luogu-CF1119F 题目大意 给你一棵树&#xff0c;给出每条边割掉的代价&#xff0c;问你对于0⩽k<n0\leqslant k<n0⩽k<n&#xff0c;使得每个点的度数小于k的最小代价 解题思路 首先考虑单询问的情况 可以设fx,1/0f_{x,1/0}fx,1/0​…

Boundary(2020多校第二场B)

Boundary&#xff08;2020多校第二场B&#xff09; 文章目录题意&#xff1a;题解&#xff1a;思路1&#xff1a;代码&#xff1a;思路二代码题意&#xff1a; 坐标平面有n个点&#xff08;不与原点&#xff08;0,0&#xff09;重复&#xff09;,现考虑一个圆&#xff0c;&…

.NET Core开发日志——Linux版本的SQL Server

SQL Server 2017版本已经可以在Linux系统上安装&#xff0c;但我在尝试.NET Core跨平台开发的时候使用的是Mac系统&#xff0c;所以这里记录了在Mac上安装SQL Server的过程。最新的SQL Server没有专门为Mac系统准备安装包&#xff0c;但由于Mac系统上支持Docker&#xff0c;所以…

P3313-[SDOI2014]旅行【树链剖分,线段树】

正题 题目链接:https://www.luogu.com.cn/problem/P3313 题目大意 nnn个点的一棵树&#xff0c;每个点有一个颜色和权值&#xff0c;有操作 修改一个点的权值修改一个点的颜色询问一条路径的某颜色的权值和询问一条路径的某颜色的权值最大值 解题思路 询问路径直接树剖先&am…

AIsing Programming Contest 2020 总结

A - Number of Multiples 按照题目意思走就行 #define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<iostream> #include<algorithm> using namespace std; int l,r,d; int main() {IO;cin>>l>>r>>d;if(r<l) swap(l,r);…

【倍增】【线段树】雨林跳跃(luogu 7599[APIO 2021 T2])

正题 luogu 7599[APIO 2021 T2] 题目大意 给你一排树中每棵树的高度&#xff0c;每次跳跃可以跳到左/右边第一棵比该树高的树&#xff0c;问你从A-B中某棵树跳到C-D中的某棵树的最小步数&#xff08;A⩽B<C⩽DA\leqslant B< C\leqslant DA⩽B<C⩽D&#xff09; 解题…

Duration(2020多校第二场D)

Duration&#xff08;2020多校第二场D&#xff09; 文章目录题意题解代码首先&#xff0c;非常感谢出题人出这个题&#xff0c;避免了我全wa的尴尬题意 求两个时间相差多少秒&#xff0c;两个时间为同一天 题解 全部转化成秒&#xff0c;然后求差 代码 #include<bits/s…