题意:给出n个点n-1条边的树,有两个操作,一个是查询节点l到r的边的最大值,然后指定边的更改权值。

题解:差不多是树链剖分的模版题,注意每个点表示的边是连向其父亲节点的边。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int M = 1e4 + 10;
struct Edge {
int v , next;
}edge[M << 1];
int head[M] , e;
int top[M];
int fa[M];
int p[M];
int fp[M];
int son[M];
int deep[M];
int num[M];
int pos;
void init() {
memset(head , -1 , sizeof(head));
memset(son , -1 , sizeof(son));
e = 0;
pos = 0;
}
void add(int u , int v) {
edge[e].v = v;
edge[e].next = head[u];
head[u] = e++;
}
void dfs1(int u , int pre , int d) {
deep[u] = d;
fa[u] = pre;
num[u] = 1;
for(int i = head[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].v;
if(v != pre) {
dfs1(v , u , d + 1);
num[u] += num[v];
if(son[u] == -1 || num[son[u]] < num[v])
son[u] = v;
}
}
}
void getpos(int u , int sp) {
top[u] = sp;
p[u] = pos++;
fp[p[u]] = u;
if(son[u] == -1)
return ;
getpos(son[u] , sp);
for(int i = head[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].v;
if(son[u] != v && v != fa[u]) {
getpos(v , v);
}
}
}
struct TnT {
int l , r , MAX;
}T[M << 2];
void pushup(int i) {
T[i].MAX = max(T[i << 1].MAX , T[(i << 1) | 1].MAX);
}
void build(int l , int r , int i) {
int mid = (l + r) >> 1;
T[i].l = l , T[i].r = r , T[i].MAX = 0;
if(T[i].l == T[i].r)
return ;
build(l , mid , i << 1);
build(mid + 1 , r , (i << 1) | 1);
pushup(i);
}
void updata(int pos , int i , int ad) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == pos && T[i].r == pos) {
T[i].MAX = ad;
return ;
}
if(mid < pos) {
updata(pos , (i << 1) | 1 , ad);
}
else {
updata(pos , i << 1 , ad);
}
pushup(i);
}
int query(int l , int r , int i) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == l && T[i].r == r) {
return T[i].MAX;
}
pushup(i);
if(mid < l) {
return query(l , r , (i << 1) | 1);
}
else if(mid >= r) {
return query(l , r , i << 1);
}
else {
return max(query(l , mid , i << 1) , query(mid + 1 , r , (i << 1) | 1));
}
}
int find(int u , int v) {
int f1 = top[u] , f2 = top[v];
int tmp = 0;
while(f1 != f2) {
if(deep[f1] < deep[f2]) {
swap(f1 , f2);
swap(u , v);
}
tmp = max(tmp , query(p[f1] , p[u] , 1));
u = fa[f1] , f1 = top[u];
}
if(u == v) return tmp;
if(deep[u] > deep[v]) swap(u , v);
return max(tmp , query(p[son[u]] , p[v] , 1));
}
int ed[M][3];
int main() {
int t , n , u , v;
scanf("%d" , &t);
while(t--) {
scanf("%d" , &n);
init();
for(int i = 0 ; i < n - 1 ; i++) {
for(int j = 0 ; j < 3 ; j++) {
scanf("%d" , &ed[i][j]);
}
add(ed[i][0] , ed[i][1]);
add(ed[i][1] , ed[i][0]);
}
dfs1(1 , 0 , 0);
getpos(1 , 1);
build(0 , pos , 1);
for(int i = 0 ; i < n - 1 ; i++) {
if(deep[ed[i][0]] > deep[ed[i][1]])
swap(ed[i][0] , ed[i][1]);
updata(p[ed[i][1]] , 1 , ed[i][2]);
}
char cp[10];
while(scanf("%s" , cp)) {
if(cp[0] == 'D')
break;
scanf("%d%d" , &u , &v);
if(cp[0] == 'C') {
updata(p[ed[u - 1][1]] , 1 , v);
}
else {
printf("%d\n" , find(u , v));
}
}
}
return 0;
}

SPOJ - QTREE(树链剖分+单点更新+区间最大值查询)的更多相关文章

  1. BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分+单点更新+区间求和+区间求最大值)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 题意:略. 题解:树链剖分模版,注意一些细节即可. #include <ios ...

  2. HDU 5274 Dylans loves tree(LCA+dfs时间戳+成段更新 OR 树链剖分+单点更新)

    Problem Description Dylans is given a tree with N nodes. All nodes have a value A[i].Nodes on tree i ...

  3. SPOJ QTREE 树链剖分

    树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...

  4. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  5. 【学术篇】SPOJ QTREE 树链剖分

    发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...

  6. QTREE 树链剖分---模板 spoj QTREE

    <树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...

  7. SPOJ 375 树链剖分 QTREE - Query on a tree

    人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...

  8. poj 2763 Housewife Wind(树链剖分+单点查询+区间修改)

    题目链接:http://poj.org/problem?id=2763 题意:给一个数,边之间有权值,然后两种操作,第一种:求任意两点的权值和,第二,修改树上两点的权值. 题解:简单的树链剖分. #i ...

  9. SPOJ 375 树链剖分

    SPOJ太慢了,SPOJ太慢了, 题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权:2.查询u,v之间路径上的最大边权. 分析:树链剖分入门题,看这里: ...

随机推荐

  1. 【JDK】JDK源码分析-AbstractQueuedSynchronizer(3)

    概述 前文「JDK源码分析-AbstractQueuedSynchronizer(2)」分析了 AQS 在独占模式下获取资源的流程,本文分析共享模式下的相关操作. 其实二者的操作大部分是类似的,理解了 ...

  2. Redhat 离线安装 Docker (Community from binaries)

    需求 在离线环境安装Docker (Community版),因为Enterprise版要花钱.当然资金充裕的客户可参考https://docs.docker.com/install/linux/doc ...

  3. oracle 删除用户,提示“无法删除当前已连接的用户”

    1. 首先查询出该用户的登录情况,注意用户名必须是大写 SQL> select username,sid,serial# from v$session where username = 'XST ...

  4. Idea搭建Spring+SpringMvc+Mybatis框架集成项目

    1.新建maven项目 2.创建多模块 每个模块配置如父模块一样,除视图层 (视图层配置) 最后 common-通过模块,不依赖任何模块,有各种项目所需要用到的工具类 model- POJO.VO.D ...

  5. Promise 学习心得

    当了这么久码农到今天没事才开始去深究 Promise 这个对象 什么是 Promise, Promise 有什么用? 在写代码的时候多多少少都有遇见过地狱式的回调 代码看起来没问题就是有点乱,Prom ...

  6. 使用windows powershell ISE管理命令窗口,并集成git命令

    写于2018-09-03(基于win10) 开启 win + s 输入 ise 操作 主要使用新建的power shell选项卡 将git集成到power shell中 安装准备 确定你的power ...

  7. struts与springmvc有何区别

    Struts2与SpringMVC有何区别? (1)SpringMVC的核心控制器是基于servlet技术,而Struts2是基于filter. (2)Struts2是类级别的拦截, 一个类对应一个r ...

  8. 全世界仅有的唯一最高LINUX版本的白菜路由,支持NAND记

    在上上篇 真千兆路由的极限之OPENWRT MAKE, 某品牌白菜价QCA9558/QCA9880/QCA8337N纯种组合OS搭建时记 里,有没有还记否之模式退一步,海阔天空 回到了远古时代的ar7 ...

  9. Python爬虫视频教程

    ├─第1章_[第0周]网络爬虫之前奏 │ ├─第1节_"网络爬虫"课程内容导学 │ │ 第1部分_全课程内容导学.mp4 │ │ 第2部分_全课程内容导学(WS00单元)学习资料. ...

  10. 写论文的第四天 Spark安装 使用sparkshell

    Spark分布式安装 Spark安装注意:需要和本机的hadoop版本对应 前往spark选择自己相对应的版本下载之后进行解压 命令:tar –zxf spark-2.4.0-bin-hadoop2. ...