Luogu P4114 Qtree1
树剖一好题。我心水了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的更多相关文章
- 【luogu P4114 Qtree1】 题解
题目链接:https://www.luogu.org/problemnew/show/P4114 1.把边权转化到点权:选取连接这条边的两个点中较深的一个. 2.查询点到点之间的边权时,要从seg[x ...
- 洛谷 P4114 Qtree1 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例: 输出样例: 说明 说明 思路 Change Query AC代码 总结 题面 题目链接 P4114 Qt ...
- 洛谷 - P4114 - Qtree1 - 重链剖分
https://www.luogu.org/problem/P4114 维护边权的话,用深度大的点表示这条边(可以遍历一边边询问两端深度,这样不需要修改dfs1,也可以在dfs1的时候向下走的同时把边 ...
- P4114 Qtree1
思路 树剖一发,注意对LCA的处理 代码 #include <cstdio> #include <algorithm> #include <cstring> usi ...
- 洛谷 P4114 Qtree1
Qtree系列都跟树有着莫大的联系,这道题当然也不例外 我是题面 读完题,我们大概就知道了,这道题非常简单,可以说是模板题.树剖+线段树轻松解决 直接看代码吧 #include<algorith ...
- 洛谷P4114 Qtree1
题目描述 给定一棵\(n\)个节点的树,有两个操作: \(CHANGE\) \(i\) \(t_i\) 把第\(i\)条边的边权变成\(t_i\) \(QUERY\) \(a\) \(b\) 输出从\ ...
- 洛谷P4114 Qtree1(树链剖分+线段树)
传送门 LCT秒天秒地用什么树剖 这题可以算是树剖的比较裸的题目了 把每一条边的权值下放到他两边的点中深度较深的那个 然后直接用树剖+线段树带进去乱搞就可以了 //minamoto #include& ...
- 树链剖分好(du)题(liu)选做
1.luogu P4315 月下"毛景树" 题目链接 前言: 这大概是本蒟蒻A掉的题里面码量最大的一道题了.我自认为码风比较紧凑,但还是写了175行. 从下午2点多调到晚上8点.中 ...
- 树链剖分【洛谷P4114】 Qtree1
P4114 Qtree1 题目描述 给定一棵n个节点的树,有两个操作: CHANGE i ti 把第i条边的边权变成ti QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0 码 ...
- 洛谷 P1505 [国家集训队]旅游 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1505 [国家集训队]旅游 题目描述 Ray 乐 ...
随机推荐
- 时间格式转换成指定格式(Vue)
1 /** 2 * Parse the time to string 3 * @param {(Object|string|number)} time 4 * @param {string} cFor ...
- 12.15linux学习第十八天
今天老刘讲了如同天书一般的隐藏章节,第23章使用OpenLDAP部署目录服务,难度太高了.第16章使用Squid部署代理缓存服务 章节概述: 本章首先介绍代理服务的原理以及作用,然后介绍Squid服务 ...
- Day03_Class01
用户交互Scanner Scanner对象 基本语法 Scanner sc = new Scanner(System.in); 通过Scanner类的next()与nextLine()方法获取输入的字 ...
- Unity各种功能实现之一:对话系统
最近根据网上的教程学习了一下Unity中的对话系统,将其中一些关键点记录下来作为参考,以后可在此基础上添加更多功能. 1.UI部分的设置. 对话框由一个panel下面的text和image组成.can ...
- NX二次开发读属性/表达式封装函数
int Read_ATTR_Type(int ObjTag, char* Attr_Title); //读取属性返回属性类型 string Read_ATTR_StringValue(int ObjT ...
- JS和PHP中能转为布尔false的值的对比
实际开发中经常会使用到JS和PHP中的变量转布尔值进行条件判断,下面对两种语言中转布尔类型结果为false的值进行对比,加深记忆和方便引用. 除了下表列出项,其它的值均转成真值true . 转布尔值后 ...
- python requests 上传文件_python3使用requests上传文件,content-type踩的坑
通常提交普通表单时,requests的post方法可以指定headers,所以我在使用requests模拟上传文件行为时,直接按照下面的方式写了: 然后服务器就报出了找不到分隔符Invalid mul ...
- Python项目案例开发从入门到实战-1.2 Python语法基础
书籍信息 1.2 Python语法基础 1.2.1 Python数据类型 数值类型 整型(int):浮点型(float):复数(complex),以j或J结尾,如2+3j 字符串 布尔类型 空值,用N ...
- spring-boot-starter-webflux
webflux: 反应式编程reactor的产物,采用发布订阅模式,引入netty的nio,比较适合IO密集型应用. 因普遍应用使用的DB链接是IO阻塞型,因此在一般应用中无法体现它的优势.redis ...
- XSS(Cross-site Scripting)-跨站脚本
XSS介绍 XSS 是基于 JavaScript 的,因此对该语言有基本的了解会很有帮助.了解XSS需要对客户端-服务器请求和响应有基本的了解 跨站点脚本,在网络安全社区中更广为人知的是 XSS,被归 ...