树剖一好题。我心水了ww

题目描述
给定一棵n个节点的树,有两个操作: CHANGE i ti 把第i条边的边权变成ti QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0 输入输出格式
输入格式:
第一行输入一个n,表示节点个数 第二行到第n行每行输入三个数,ui,vi,wi,分别表示 ui,vi有一条边,边权是wi 第n+1行开始,一共有不定数量行,每一行分别有以下三种可能 CHANGE,QUERY同题意所述 DONE表示输入结束 输出格式:
对于每个QUERY操作,输出一个数,表示a b之间边权最大值

树链剖分维护。若对应的一组父亲节点\(x\)与子节点\(y\)之间有一条边,则将边权存为\(y\)点的点权。在dfs2内特殊处理即可。

对于修改,线段树动态维护一下最大值。

查询路径最大值按照常规树剖的跳链写法就可以了。由于是边权存为点权,不能计算最近公共祖先。\(LCA\)所代表的那条边并不在路径上qwq

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define MAXN 102333
using namespace std;
int h[MAXN],tot=0,cnt=0;
int n,m;
struct qwq
{
int nex,to,w;
int id;
}e[MAXN<<1];
int ans[MAXN<<2];
int w1[MAXN];
int dep[MAXN],son[MAXN]={},fa[MAXN],top[MAXN],siz[MAXN],id[MAXN]; inline void add(int x,int y,int w,int i)
{
e[++tot].to=y;
e[tot].nex=h[x];
e[tot].w=w;
e[tot].id=i;
h[x]=tot;
}
#define leftson cur<<1
#define rightson cur<<1|1
#define mid ((l+r)>>1)
#define push_up ans[cur]=max(ans[leftson],ans[rightson])
inline void build(int cur,int l,int r)
{
if (l==r)
{
ans[cur]=w1[l];
return;
}
build(leftson,l,mid);
build(rightson,mid+1,r);
push_up;
}
int tag[MAXN<<2];
#define push_down lazyadd(leftson,tag[cur]); lazyadd(rightson,tag[cur]); tag[cur]=0
inline void lazyadd(int cur,int del)
{
if (!del) return;
ans[cur]+=del;
tag[cur]+=del;
}
void change(int adl,int adr,int cur,int l,int r,int del)
{
if (adl<=l&&r<=adr)
{
ans[cur]=del;
tag[cur]=del;
return;
}
push_down;
if (adl<=mid) change(adl,adr,leftson,l,mid,del);
if (adl>mid) change(adl,adr,rightson,mid+1,r,del);
push_up;
}
int query(int ql,int qr,int cur,int l,int r)
{
if (ql<=l&&r<=qr)
{
return ans[cur];
}
int answ=-23333;
push_down;
if (ql<=mid) answ=max(answ,query(ql,qr,leftson,l,mid));
if (qr>mid) answ=max(answ,query(ql,qr,rightson,mid+1,r));
return answ;
} int segid[MAXN];
void dfs_fir(int x,int f,int dept)
{
fa[x]=f;
dep[x]=dept;
siz[x]=1;
int maxn=-1;
for (int i=h[x],y;i;i=e[i].nex)
{
y=e[i].to;
if (y==f) continue;
dfs_fir(y,x,dept+1);
siz[x]+=siz[y];
if (siz[y]>maxn)
{
son[x]=y;
maxn=siz[y];
}
}
}
void dfs_sec(int x,int ft,int w)
{
top[x]=ft;
id[x]=++cnt;
w1[cnt]=w;
if (!son[x]) return;
dfs_sec(son[x],ft,0);
for (int i=h[x],y;i;i=e[i].nex)
{
y=e[i].to;
if (y==fa[x]) continue;
if (y==son[x])
{
w1[id[son[x]]]=e[i].w;
segid[e[i].id]=id[son[x]];
continue;
}
dfs_sec(y,y,e[i].w);
segid[e[i].id]=id[y];
}
}
inline int query_(int x,int y)
{
int answer=-23333;
while (top[x]!=top[y])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
answer=max(answer,query(id[top[x]],id[x],1,1,n));
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
answer=max(answer,query(id[x]+1,id[y],1,1,n));
return answer;
} int main()
{
scanf("%d",&n);
int x,y,w;
for (int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&w);
add(x,y,w,i);
add(y,x,w,i);
}
dfs_fir(1,1,1);
dfs_sec(1,1,0);
build(1,1,n);
string s="QWQ";
// for (int i=1;i<=n;i++)
// {
// printf("%d ",w1[id[i]]);
// }
// printf("\n\n");
while (s[0]!='D')
{
cin>>s;
if (s[0]=='D') continue;
scanf("%d%d",&x,&y);
if (s[0]=='Q')
{
if (x==y)
{
printf("0\n");
continue;
}
printf("%d\n",query_(x,y));
continue;
}
change(segid[x],segid[x],1,1,n,y);
}
return 0;
}

Luogu P4114 Qtree1的更多相关文章

  1. 【luogu P4114 Qtree1】 题解

    题目链接:https://www.luogu.org/problemnew/show/P4114 1.把边权转化到点权:选取连接这条边的两个点中较深的一个. 2.查询点到点之间的边权时,要从seg[x ...

  2. 洛谷 P4114 Qtree1 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例: 输出样例: 说明 说明 思路 Change Query AC代码 总结 题面 题目链接 P4114 Qt ...

  3. 洛谷 - P4114 - Qtree1 - 重链剖分

    https://www.luogu.org/problem/P4114 维护边权的话,用深度大的点表示这条边(可以遍历一边边询问两端深度,这样不需要修改dfs1,也可以在dfs1的时候向下走的同时把边 ...

  4. P4114 Qtree1

    思路 树剖一发,注意对LCA的处理 代码 #include <cstdio> #include <algorithm> #include <cstring> usi ...

  5. 洛谷 P4114 Qtree1

    Qtree系列都跟树有着莫大的联系,这道题当然也不例外 我是题面 读完题,我们大概就知道了,这道题非常简单,可以说是模板题.树剖+线段树轻松解决 直接看代码吧 #include<algorith ...

  6. 洛谷P4114 Qtree1

    题目描述 给定一棵\(n\)个节点的树,有两个操作: \(CHANGE\) \(i\) \(t_i\) 把第\(i\)条边的边权变成\(t_i\) \(QUERY\) \(a\) \(b\) 输出从\ ...

  7. 洛谷P4114 Qtree1(树链剖分+线段树)

    传送门 LCT秒天秒地用什么树剖 这题可以算是树剖的比较裸的题目了 把每一条边的权值下放到他两边的点中深度较深的那个 然后直接用树剖+线段树带进去乱搞就可以了 //minamoto #include& ...

  8. 树链剖分好(du)题(liu)选做

    1.luogu P4315 月下"毛景树" 题目链接 前言: 这大概是本蒟蒻A掉的题里面码量最大的一道题了.我自认为码风比较紧凑,但还是写了175行. 从下午2点多调到晚上8点.中 ...

  9. 树链剖分【洛谷P4114】 Qtree1

    P4114 Qtree1 题目描述 给定一棵n个节点的树,有两个操作: CHANGE i ti 把第i条边的边权变成ti QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0 码 ...

  10. 洛谷 P1505 [国家集训队]旅游 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1505 [国家集训队]旅游 题目描述 Ray 乐 ...

随机推荐

  1. 修改浏览器搜索引擎:设置网址格式(用“%s”代替搜索字词)

    浏览器搜索引擎设置,如何填写网址格式(用"%s"代替搜索字词)? 以下收集部分: 综合检索 名称 关键字 网址(用"%s"代替搜索字词) 必应 cn.bing. ...

  2. vs xamarin获取sha1申请百度sdk密钥

    请查看微软帮助文档 查找密钥存储的签名 - Xamarin | Microsoft Docs

  3. FII-PRA006/010开发板硬件实验一

    FII-PRA006/010开发板硬件实验一 以一位全加器为例介绍如何利用开发板进行板载实验.一位全加器的Verilog代码如下: 1 2 3 4 5 6 7 8 9 10 module fadd1 ...

  4. python excel使用

    python excel使用 https://blog.csdn.net/m0_59235508/article/details/122808875 pandas不覆盖写入 https://blog. ...

  5. Testlink for linux by Xampp

    Testlink 1.环境: (1)需要的环境配置: ①Linux system. ②Mysql ③apache ④Php (2)上面的2,3,4我们使用简易的Xamppp集成的环境,下面是安装配置x ...

  6. 【Unity】利用C#反射打印类的字段信息

    最近在用protobuf-net序列化功能生成.bytes配置文件时,遇到了需要把.bytes配置文件再另外转成Lua配置文件(Lua配置表内容举例)的需求.Lua配置文件需要记录配置类的各个字段名和 ...

  7. python C# DES 加密转换

    import time import base64 import pyDes import binascii def DESEncrypt(desKey, target): key = desKey[ ...

  8. Hive不能载入本地数据:FAILED: SemanticException Line 1:17 Invalid path

    1.问题描述: (1)问题示例: hive (test)> create table t_textfile(c1 string,c2 int,c3 string,c4 string)      ...

  9. Apache + PHP + Mysql Windows下配置

    1.安装Apache 下载网址 http://httpd.apache.org/download.cgi#apache24 二.下载php 下载地址:https://www.php.net/downl ...

  10. Matlab:读取、写入(.txt)(.xlsx)

    写入txt a=[1,2,3;4,5,6]; save C:\Users\Administrator\Desktop\a.txt -ascii a 参考:https://blog.csdn.net/h ...