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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define lson left, mid, rt<<1
#define rson mid + 1, right, rt<<1|1
using namespace std;
const ll maxn = 300000 + 10;
char opt[9];
ll n, m, root, res;
ll top[maxn], rev[maxn], seg[maxn], son[maxn];
ll fa[maxn], size[maxn], deep[maxn];
ll u[maxn], v[maxn], w[maxn];
ll tree[maxn<<2], lazy[maxn<<2], num, node[maxn];
struct edge{ll next, from, to, len;
}e[maxn<<2];
ll head[maxn], cnt;
void add(ll u, ll v, ll w)
{e[++cnt].from = u;e[cnt].len = w;e[cnt].next = head[u];e[cnt].to = v;head[u] = cnt;
}
//-----segment_tree-----
void PushUP(ll rt)
{tree[rt] = max(tree[rt<<1], tree[rt<<1|1]);
}
void build(ll left, ll right, ll rt)
{if(left == right){tree[rt] = rev[left];return;}ll mid = (left + right)>>1;build(lson);build(rson);PushUP(rt);
}
void PushDOWN(ll rt)
{lazy[rt<<1] = lazy[rt];lazy[rt<<1|1] = lazy[rt];tree[rt<<1] = lazy[rt];tree[rt<<1|1] = lazy[rt];lazy[rt] = 0;
}
void update(ll l, ll r, ll add, ll left, ll right, ll rt)
{if(l <= left && r >= right){tree[rt] = add;lazy[rt] = add;return;}ll mid = (left + right)>>1;if(lazy[rt]) PushDOWN(rt);if(l <= mid) update(l, r, add, lson);if(r > mid) update(l, r, add, rson);PushUP(rt);
}
ll query(ll l, ll r, ll left, ll right, ll rt)
{ll res = -0x7fffffff;if(l <= left && r >= right){return tree[rt];}ll mid = (left + right)>>1;if(lazy[rt]) PushDOWN(rt);if(l <= mid) res = max(res, query(l, r, lson));if(r > mid) res = max(res, query(l, r, rson));return res;
}
//----------------------
void dfs1(ll u, ll f, ll d)
{ll maxson = -1;size[u] = 1;deep[u] = d;fa[u] = f;for(ll i = head[u]; i != -1; i = e[i].next){ll v = e[i].to;if(f != v){dfs1(v, u, d+1);size[u] += size[v];if(size[v] > maxson) son[u] = v, maxson = size[v];}}
}
void dfs2(ll u, ll t)
{seg[u] = ++num;rev[num] = node[u];top[u] = t;if(!son[u]) return;dfs2(son[u], t);for(ll i = head[u]; i != -1; i = e[i].next){ll v = e[i].to;if(v == son[u] || v == fa[u]) continue;dfs2(v,v);}
}
void updRange(ll x, ll y, ll k)
{while(top[x] != top[y]){if(deep[top[x]] < deep[top[y]]) swap(x, y);update(seg[top[x]], seg[x], k, 1, n, 1);x = fa[top[x]];}if(deep[x] > deep[y]) swap(x, y);update(seg[x], seg[y], k, 1, n, 1);
}
ll qRange(ll x, ll y)
{ll ans = 0;while(top[x] != top[y]){if(deep[top[x]] < deep[top[y]]) swap(x, y);res = 0;res = query(seg[top[x]], seg[x], 1, n, 1);ans = max(res, ans);x = fa[top[x]];}if(deep[x] > deep[y]) swap(x, y);res = 0;res = query(seg[x]+1, seg[y], 1, n, 1);ans = max(res, ans);return ans;
}
int main()
{memset(head, -1, sizeof(head));scanf("%lld",&n);root = 1;for(ll i = 1; i < n; i++){scanf("%lld%lld%lld",&u[i],&v[i],&w[i]);add(u[i],v[i],w[i]); add(v[i],u[i],w[i]);}dfs1(root, 0, 1);//for(int i = 1; i <= n; i++) cout<<deep[i]<<" ";for(ll i = 1; i < n; i++){if(deep[u[i]] < deep[v[i]]) node[v[i]] = w[i];else node[u[i]] = w[i];}//for(int i = 1; i <= n; i++) cout<<node[i]<<" ";dfs2(root, root);build(1, n, 1);while(cin>>opt && opt[0] != 'D'){ll x, y, z;if(opt[0] == 'C'){scanf("%lld%lld",&x,&y);if(deep[u[x]] > deep[v[x]]) updRange(u[x], u[x], y);else updRange(v[x], v[x], y);}else{scanf("%lld%lld",&x,&y);if(x == y){printf("0\n");continue;}printf("%lld\n",qRange(x,y));}}
}

转载于:https://www.cnblogs.com/MisakaAzusa/p/9416364.html

【luogu P4114 Qtree1】 题解相关推荐

  1. 【luogu P3946 ことりのおやつ】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3946 交好几遍是因为虽然能过一直有提醒..强迫症qwq #include <bits/stdc++.h ...

  2. Luogu P3399 丝绸之路 题解

    原题传送门 题目背景 张骞于公元前138年曾历尽艰险出使过西域.加强了汉朝与西域各国的友好往来.从那以后,一队队骆驼商队在这漫长的商贸大道上行进,他们越过崇山峻岭,将中国的先进技术带向中亚.西亚和欧洲 ...

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

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

  4. Luogu P1550 [USACO08OCT]打井Watering Hole

    0号结点:农夫John山泉天然矿泉水( by Luogu第一篇题解 #include<cstdio> #include<cstring> #include<algorit ...

  5. Luogu 2495 [SDOI2011]消耗战

    BZOJ 2286 传说中的虚树经典题. 放上我觉得讲的很好的Luogu置顶题解.       传送门 首先考虑一个暴力的$dp$,设$f_x$表示切断$x$的子树中的所有特殊点且保留$x$的最小代价 ...

  6. 洛谷P1035题解 [NOIP2002 普及组] 级数求和

    原文地址:https://luvletter.blog.luogu.org/p1035-ti-jie 题解 本体难度不大,但要注意计算和的时候要使用double类型,千万不能使用float类型,不然会 ...

  7. 洛谷P1055题解 [NOIP2008 普及组] ISBN 号码

    原文地址:https://luvletter.blog.luogu.org/p1055-ti-jie 题解 超级简单的一题,就是要注意输入和输出的分隔符的问题以及ASCII码中0~9这10个数字对应的 ...

  8. 【分块】[LUOGU 旅行规划] 分块+二分+凸包优化

    题目: 题目链接:[LUOGU 旅行规划] 题解: (由于这个,,我竟然还去写了二维凸包的模板题作为练习,,,然而,一点用都没有,,,,) 先解释一下题面的意思:就是一个区间加的操作,再加上一个区间的 ...

  9. 【洛谷题解】P5734 【深基6.例6】文字处理软件(C语言)

    P5734 [深基6.例6]文字处理软件 题目描述 你需要开发一款文字处理软件.最开始时输入一个字符串(不超过 100 个字符)作为初始文档.可以认为文档开头是第 0 个字符.需要支持以下操作: 1 ...

  10. P2858 [USACO06FEB]Treats for the Cows G/S 题解

    emmmmmm,第二篇文章,多多写文章,好好掌握知识! 前言 原本在educoder上刷题,刷到[粉刷匠]一题,使用区间DP来做的.自己之前曾经小部分刷过背包DP的题目,对于区间DP还是知之甚少.在稍 ...

最新文章

  1. post 返回代码_减少冗长代码,利用DDT轻松分离测试数据
  2. DatabaseMetaData.getIndexInfo
  3. 全卷积(FCN)论文阅读笔记:Fully Convolutional Networks for Semantic Segmentation
  4. ggbiplot设置分组_R语言安装ggbiplot
  5. mime类型是什么类型_使用多种MIME类型测试REST
  6. mysql 游标中实现递归_mysql中实现递归查询?
  7. 图像识别算法超低代码开发方案
  8. 有限时间不明确需求项目的上线(部分还款)
  9. 如何在桌面添加计算机日历工具,Win7电脑在桌面添加时钟、日历、货币、天气、CPU仪表盘小工具方法...
  10. 多态性练习:定义一个基类BaseClass,从他派生出类DerivedClass。BaseClass有成员函数 fn1(),fn2()
  11. iOS逆向--MachoO文件
  12. 3D数学基础——Rotator类的C++实现
  13. OpenCV Error:Insufficient memory(Failed to allocate 1244164 bytes)
  14. 静态库与动态库的区别
  15. facebook审核流程
  16. 使用getElementsByTagName()和namedItem()获取特定元素
  17. 雷神之战html5游戏在线玩,每周30命!5.2雷电王座BOSS莱登限制挑战次数
  18. STC89C52串口向电脑发送数据
  19. 会议录音转文字的软件有哪些?这款软件试试看
  20. excel做地图热力图_中国数据地图(热力图)-到市级-分档填色

热门文章

  1. OWASP Hakcing Lab在线漏洞环境
  2. eclipse adt开发android ndk没有NDK选项问题的解决方案
  3. webpack热更新和常见错误处理
  4. Script:列出Oracle每小时的redo重做日志产生量
  5. ivew select组件 DatePicker组件的清空
  6. 利用Hibernate进行数据库的增删改查
  7. ASP.NET之MVC 微信公众号授权给第三方平台的技术实现流程一(获取第三方平台access_token)...
  8. C# 中using的几个用途
  9. 通过SQL Server 2008数据库复制实现数据库同步备份
  10. Asp.net can do Native Code also can do it(updated)