SPOJ375 Query on a tree(树链剖分)
题意
给出一棵树,每条边都有权值,有两种操作:
- 把第p条边的权值改为x
- 询问x,y路径上的权值最大的边
code
#include<cstdio>
#include<algorithm>
#include<cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 using namespace std; const int N = ;
struct Edge {
int to,nxt,w;
}e[];
int head[N],tot,tn,n;
int deth[N],son[N],fa[N],siz[N],bel[N],pos[N];
int mx[N<<],a[N],b[N],c[N],data[N]; void init() {
tot = tn = ;
memset(head,,sizeof(head));
memset(son,,sizeof(son));
}
inline void add_edge(int u,int v,int w) {
e[++tot].to = v,e[tot].w = w,e[tot].nxt = head[u],head[u] = tot;
}
void dfs1(int u,int pa) {
siz[u] = ;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v==pa) continue;
fa[v] = u;
deth[v] = deth[u] + ;
dfs1(v,u);
siz[u] += siz[v];
if (son[u]== || siz[v] > siz[son[u]]) son[u] = v;
}
}
void dfs2(int u,int top) {
pos[u] = ++tn;
bel[u] = top;
if (!son[u]) return ;
dfs2(son[u],top);
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v != fa[u] && v != son[u]) dfs2(v,v);
}
}
void pushup(int rt) {
mx[rt] = max(mx[rt<<],mx[rt<<|]);
}
void build(int l,int r,int rt) {
if (l==r) {
mx[rt] = data[l];return ;
}
int m = (l + r) >> ;
build(lson);
build(rson);
pushup(rt);
}
void update(int l,int r,int rt,int p,int x) {
if (l==r) {
mx[rt] = x;return ;
}
int m = (l + r) >> ;
if (p <= m) update(lson,p,x);
else update(rson,p,x);
pushup(rt);
}
int query(int l,int r,int rt,int L,int R) {
if (L <= l && r <= R) {
return mx[rt];
}
int m = (l + r) >> ;
int ret = -1e9;
if (L <= m) ret = max(ret,query(lson,L,R));
if (R > m) ret = max(ret,query(rson,L,R));
return ret;
}
void Change(int p,int x) {
if (deth[a[p]] > deth[b[p]]) update(,n,,pos[a[p]],x);
else update(,n,,pos[b[p]],x);
}
int Ask(int x,int y) {
int ans = -1e9;
while (bel[x] != bel[y]) {
if (deth[bel[x]] < deth[bel[y]]) swap(x,y);
ans = max(ans,query(,n,,pos[bel[x]],pos[x]));
x = fa[bel[x]];
}
if (deth[x] > deth[y]) swap(x,y);
if (x != y) ans = max(ans,query(,n,,pos[x]+,pos[y]));
return ans;
}
int main() {
char opt[];
int T;scanf("%d",&T);
while (T--) {
init();
scanf("%d",&n);
for (int i=; i<n; ++i) {
scanf("%d%d%d",&a[i],&b[i],&c[i]);
add_edge(a[i],b[i],c[i]);
add_edge(b[i],a[i],c[i]);
}
deth[] = ;
dfs1(,);
dfs2(,);
for (int i=; i<n; ++i) {
if (deth[a[i]] > deth[b[i]]) data[pos[a[i]]] = c[i]; // 一定是pos
else data[pos[b[i]]] = c[i];
}
build(,n,);
scanf("%s",opt);
while (opt[]!='D') {
int x,y;
scanf("%d%d",&x,&y);
if (opt[]=='Q') printf("%d\n",Ask(x,y));
else Change(x,y);
scanf("%s",opt);
}
}
return ;
}
SPOJ375 Query on a tree(树链剖分)的更多相关文章
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- SPOJ QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- spoj 375 Query on a tree (树链剖分)
Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges ...
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- SPOJ QTREE Query on a tree ——树链剖分 线段树
[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...
- SPOJ 375 Query on a tree 树链剖分模板
第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
随机推荐
- sql 2008 中不能创建数据库关系图
执行以下命令: ALTER AUTHORIZATION ON DATABASE::[databasename] TO sa [databasename] 为数据库名: 此方法借鉴于<老高> ...
- 阿里开发搜索(OpenSearch)的学习与使用
概述: 开放搜索(OpenSearch)是一款结构化数据搜索托管服务,为移动应用开发者和网站站长提供简单.高效.稳定.低成本和可扩展的搜索解决方案. OpenSearch基于阿里巴巴自主研发的大规模分 ...
- 20170405JDBC数据查询
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...
- java中的常用内存区域总结
<开发实战经典> (1)栈内存空间:保存所有的对象名称 (2)堆内存空间:保存每个对象的具体属性内容 (3)全局数据区:保存static类型的属性 (4)全 ...
- 如何正确配置 Nginx + PHP ???
本文转自如何正确配置 Nginx + PHP,如有侵权,请联系管理员及时删除!
- 云计算的那些「What」
本文从云计算讲起,介绍了选择云计算的各种理由和一些最基本的概念. 经过十多年发展,云计算早已成为不可阻挡的技术潮流,逐渐深入到各行各业,不同规模的组织中,帮助用户以更低运营成本获得完善高效的 IT 服 ...
- POJ 3252 Round Numbers (区间DP,基础)
题意: 统计区间[L,R]有多少个数,其二进制表示法中的0的个数不少于1的个数?(不允许前缀0) 思路: 状态表示为 [当前第几位][总位数][1的个数],最后判断一下1的个数是否满足条件,要注意前导 ...
- hiho一下 第四十四周 博弈游戏·Nim游戏(直接公式解)
证明看这http://hihocoder.com/contest/hiho44/problem/1 思路: 设 sg=a[1]^a[2]^...a[n],若sg=0,则先手Alice必败,否则必赢. ...
- python爬虫之路——正则表达式初识
正则表达式:是一个特殊的符号系列,检查字符串是否与指定模式匹配. python中的re模块拥有全部的正则表达式功能. 判断字符: 类型: 数目:有无: 个数:单值 区间 离散 判 ...
- 【Orange Pi Lite2】 ——1《如何开始使用开源硬件》
[Orange Pi Lite2] --1<如何开始使用开源硬件> 本文只在博客园发布 在开始前你需要准备的材料与软件 用户手册_Orange Pi Lite2 OrangePi_Lite ...