当前位置: 首页 > news >正文

P6845 题解

P6845
他是一个带修改的直径,直径就是两点间最长距离,很容易想到用差分,\(dis_x\) 表示 \(x\) 到根节点的距离 \(dis_x + dis_y - 2dis_{lca(x,y)}\) 去求,先抛开这个 \(lca\) , 修改一条边相当于修改这个边所对应的子树,显然可以用线段树去做,搞一个 \(dfs\) 序,改的话就用加标记,维护 \(mx,ans\) , \(ans_x = max(ans_{ls},ans_{rs},mx_{ls}+mx_{rs})\) 全部这其中难办的点就是这个 \(lca\) ,想到可以用欧拉序来求,我们会发现两点 \(lca\) 在两点所夹的区间中,且是这个区间里的 \(dis_{min}\),可是单个 \(lca\) 比较难求,我们可以做一步转化,将点转到序列上,在这个区间中正确的 \(lca\) 所产生的就一定是这个区间里贡献最大的,所以即使考虑其他区间中的点也对答案没有影响,所以转化为了:

  1. 区间修改
  2. 给你 \(a,c\) ,对于 \(b\)\(a \le b \le c\) ,求 \(s_a + s_c - 2s_b\) 最大值

由于这三个数是有位置限制,那么合并的时候有位置限制的两个数就可以前面的从 \(ls\) 转移,后面的从 \(rs\) 转移,所以可以考虑维护 \(mx,mn,ab,bc,abc,lzy\) ,如 \(abc_x = max(abc_{ls},abc_{rs},ab_{ls}+mx_{rs},mx_{ls}+ab_{rs})\) ,其他的随便转移即可。

#include <bits/stdc++.h>
#define int long long
#define maxn 100010
#define pb push_back
#define vec vector
#define pii pair<int,int>
#define fir first
#define sec second
#define ls (x << 1)
#define rs (x << 1 | 1)
#define mid ((l + r) >> 1)
using namespace std;
int n,q,w;
vec <pii> v[maxn];
struct edge{int x,y,w;
}e[maxn];
int dfn[maxn << 1];
int l[maxn],r[maxn];
int tot = 0;
int dep[maxn];
int dis[maxn];
struct node{int mx,mn;int ab,bc,abc;int lzy;
}s[maxn << 3];
void dfs(int x,int fa){dfn[++tot] = x;dep[x] = dep[fa] + 1;l[x] = tot;for(auto to : v[x]){int y = to.fir,w = to.sec;if(y == fa){continue;}dis[y] = dis[x] + w;dfs(y,x);dfn[++tot] = x; }r[x] = tot;
}
void up(int x){s[x].mn = min(s[ls].mn,s[rs].mn);s[x].mx = max(s[ls].mx,s[rs].mx);s[x].ab = max(s[ls].mx - s[rs].mn * 2,max(s[ls].ab,s[rs].ab));s[x].bc = max(s[rs].mx - s[ls].mn * 2,max(s[ls].bc,s[rs].bc));s[x].abc = max(max(s[ls].abc,s[rs].abc),max(s[ls].mx + s[rs].bc,s[ls].ab + s[rs].mx));
}
void build(int x,int l,int r){if(l == r){int now = dis[dfn[l]];s[x] = {now,now,-now,-now,0};return ; }build(ls,l,mid);build(rs,mid + 1,r);up(x);
}
void down(int x){s[ls].lzy += s[x].lzy;s[rs].lzy += s[x].lzy;s[ls].mn += s[x].lzy;s[rs].mn += s[x].lzy;s[ls].mx += s[x].lzy;s[rs].mx += s[x].lzy;s[ls].ab -= s[x].lzy;s[rs].ab -= s[x].lzy;s[ls].bc -= s[x].lzy;s[rs].bc -= s[x].lzy;s[x].lzy = 0;
}
void modify(int x,int l,int r,int L,int R,int v){if(L <= l && R >= r){s[x].mx += v;s[x].mn += v;s[x].ab -= v;s[x].bc -= v;s[x].lzy += v;return ;}if(s[x].lzy){down(x);}if(L <= mid){modify(ls,l,mid,L,R,v);}if(R > mid){modify(rs,mid + 1,r,L,R,v);}up(x);
}
signed main(){cin >> n >> q >> w;for(int i = 1,x,y,z;i < n;i++){cin >> x >> y >> z;v[x].pb({y,z});v[y].pb({x,z});e[i] = {x,y,z};}dfs(1,0);build(1,1,tot);int ans = 0;for(int i = 1,x,y;i <= q;i++){cin >> x >> y;x = (x + ans) % (n - 1) + 1;y = (y + ans) % w;int now;if(dep[e[x].x] < dep[e[x].y]){now = e[x].y;}else{now = e[x].x; }modify(1,1,tot,l[now],r[now],y - e[x].w);e[x].w = y;ans = s[1].abc;cout << ans << endl;}
}
http://www.hskmm.com/?act=detail&tid=36854

相关文章:

  • LGP3694 邦邦的大合唱站队 学习笔记
  • 2025.10.22学习记录
  • 衡量效率,质量,运维的效率指标
  • LeeCode_101对称二叉树
  • TRAE 设计团队如何玩转 Vibe Coding(上)|高美感页面生成篇
  • LeeCode_226反转二叉树
  • 2025多校冲刺CSP模拟赛7 总结
  • 详细介绍:wpf之 Popup
  • 结对项目-生成四则运算
  • ? #4
  • CSS3 超实用属性:pointer-events (可穿透图层的鼠标事件)
  • 类和对象
  • 取证-windbg和dmp,以及文件分析基本流程
  • 【比赛记录】2025CSP+NOIP 冲刺模拟赛合集Ⅱ
  • 羊驼二次免疫的六大风险:纳米抗体制备不可忽视的 “隐形陷阱”
  • 完整教程:C++项目:仿muduo库高并发服务器-------connection模块
  • 深入解析:线性代数 SVD | 令人困扰的精度 1
  • 营销数字化专家要求
  • 小程序反编译包的架构文件
  • 10.22 CSP-S模拟37/2025多校冲刺CSP模拟赛7 改题记录
  • [题解]P11126 [ROIR 2024] 三等分的数组 (Day 2)
  • Acrobat Pro DC 2025下载及破解安装教程,附永久免费免激活中文版Acrobat Pro DC安装包(稳定版)
  • VSLAM 十四讲--阅读中知识点记录
  • 数据库学习篇(持续更新中)
  • Fortinet产品安全漏洞分析:FGFM协议未经认证连接重置漏洞
  • 李超线段树
  • fiddler修改请求(修改搜索框的内容)
  • 20251022
  • 10月22号
  • 将“百度”的URL改为“163网易云”(修改URL地址)