树链剖分-SPOJ375(QTREE)
QTREE - Query on a tree
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
- CHANGE i ti : change the cost of the i-th edge to ti
or - QUERY a b : ask for the maximum edge cost on the path from node a to node b
Input
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
- In the first line there is an integer N (N <= 10000),
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),
- The next lines contain instructions "CHANGE i ti" or "QUERY a b",
- The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "QUERY" operation, write one integer representing its result.
Example
Input:
1 3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE Output:
1
3 传送门
一句话题意:给出一棵树,要求在树上:
1)更新某个节点的值
2)求两个节点间最短路径上的最大值 模板题,数据结构解析详见代码。
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define clr(a) memset(a,0,sizeof(a));
#define foru(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int N=;
struct edge{int to,nxt;}e[N*];
int t[N],a[N][],d[N],id[N],head[N],f[N],siz[N],son[N],top[N];
//f[v] 节点v的父节点编号
//id[v] 节点v的父边在线段树中的编号
//siz[v] 以节点v为根的数中的节点数
//son[v] 节点v的子节点中siz[]最大的节点编号
//top[v] 节点v所在重链的顶端节点编号
//d[v] 节点v的深度
int ne,cnt,n; void add(int a,int b){
e[++ne]=(edge){b,head[a]};head[a]=ne;
} /////////////////////////////树剖//////////////////////////////////// void dfs(int k,int fa,int dep){//统计f[] siz[] son[] d[]
f[k]=fa;d[k]=dep;siz[k]=;son[k]=;
for(int i=head[k];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;//无向图判是否走过,易漏
dfs(v,k,dep+);
siz[k]+=siz[v];
if(siz[v]>siz[son[k]])son[k]=v;
}
} void build(int k,int tp){
id[k]=++cnt;//按序将边加入线段树
top[k]=tp;
if(son[k])build(son[k],tp);//重儿子的top[]从重链顶端继承
for(int i=head[k];i;i=e[i].nxt)
if(e[i].to!=son[k]&&e[i].to!=f[k])
build(e[i].to,e[i].to);//轻儿子top[]为自身
}
/////////////////////////////树剖//////////////////////////////////// /////////////////////////////线段树////////////////////////////////////
#define mid ((L+R)>>1)
#define ls (k<<1)//写位运算一定要开-Wall,否则一定要记得加括号
#define rs ls+1 void update(int k,int L,int R,int p,int x){
if(p>R||p<L)return;
if(L==R){t[k]=x;return;}
update(ls,L,mid,p,x); update(rs,mid+,R,p,x);
t[k]=max(t[ls],t[rs]);
} int query(int k,int L,int R,int l,int r){
if(l>R||r<L)return ;
if(l<=L&&R<=r)return t[k];
return max(query(ls,L,mid,l,r),query(rs,mid+,R,l,r));
}
/////////////////////////////线段树//////////////////////////////////// int find(int x,int y){
int ans=-1e9;
while(top[x]!=top[y]){//类似LCA,每次将较低的节点上跳,并统计路径上的最大值
if(d[top[x]]<d[top[y]])swap(x,y);
ans=max(ans,query(,,cnt,id[top[x]],id[x]));
x=f[top[x]];
}
if(d[x]>d[y])swap(x,y);//当两点处于同一条链上的时候,进行最后一次统计
if(x!=y)ans=max(ans,query(,,cnt,id[x]+,id[y]));//注意,因为id[x]为x的父边,所以若不+1,就会多统计一条边
return ans;
} char ch[];
void work(){
int x,y;
while(scanf("%s",ch),ch[]!='D'){
scanf("%d%d",&x,&y);
if(ch[]=='C')update(,,cnt,id[a[x][]],y);
else printf("%d\n",find(x,y));
}
} void init(){
clr(a);clr(e);clr(t);clr(son);clr(siz);clr(id);clr(top);clr(head);clr(d);clr(f);
ne=cnt=n=;
scanf("%d",&n);
foru(i,,n-){
scanf("%d%d%d",&a[i][],&a[i][],&a[i][]);
add(a[i][],a[i][]);add(a[i][],a[i][]);
}
dfs(,,);
build(,);
foru(i,,n-){
if(d[a[i][]]>d[a[i][]])swap(a[i][],a[i][]);
update(,,cnt,id[a[i][]],a[i][]);//建树
}
} int main(){
int T;
scanf("%d",&T);
while(T--){
init();
work();
}
}
树链剖分-SPOJ375(QTREE)的更多相关文章
- Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划
题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆ 输入文件:qtree.in ...
- SPOJ375.QTREE树链剖分
题意:一个树,a b c 代表a--b边的权值为c.CHANGE x y 把输入的第x条边的权值改为y,QUERY x y 查询x--y路径上边的权值的最大值. 第一次写树链剖分,其实树链剖分只能说 ...
- [SPOJ375]QTREE - Query on a tree【树链剖分】
题目描述 给你一棵树,两种操作. 修改边权,查找边权的最大值. 分析 我们都知道,树链剖分能够维护点权. 而且每一条边只有一个,且唯一对应一个儿子节点,那么就把信息放到这个儿子节点上. 注意,lca的 ...
- QTREE 树链剖分---模板 spoj QTREE
<树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- 树链剖分边权模板spoj375
树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...
- 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(树链剖分)(QTREE)
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- SPOJ QTree【树链剖分】
一 题目 QTREE 二 分析 第一道树链剖分的题,写的好艰难啊. 题意还是比较好理解的,就是在树上操作. 对于修改,题中要求的是单点修改,就算是直接树上操作也是非常简单的. 对于查询,查询的时候,是 ...
随机推荐
- DDD创始人Eric Vans:要实现DDD原始意图,必须CQRS+Event Sourcing架构
http://www.infoq.com/interviews/Technology-Influences-DDD# 要实现DDD(domain drive design 领域驱动设计)原始意图,必 ...
- Node v0.12.5 稳定版发布
Node v0.12.5 稳定版发布了,该版本改进记录主要包括: openssl: upgrade to 1.0.1o (Addressing multiple CVEs) npm: upgrade ...
- js原生轮播图
轮播图是新手学前端的必经之路! 直接上代码! <!DOCTYPE html><html lang="en"><head> <meta ch ...
- MongoDB基础之六 索引
一 . 索引概述和基本操作 1. 索引提高查询速度,降低写入速度,权衡常用的查询字段,不必在太多列上建索引2. 在mongodb中,索引可以按字段升序/降序来创建,便于排序3. 默认是用btree来组 ...
- iOS WebViewJavascriptBridge初步尝试与图文详细讲解
JS和OC的交互这是个永恒话题,使用场景也是越来越多,如今一些reactnative.vue框架等,都是在重点结合原生与H5的混合使用. 那么,如何快捷方便的使用两者交互是一个很重要的关键点. 1.传 ...
- C++编程练习(5)----“实现简单的循环队列的顺序存储结构“
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 队列是一种先进先出(First In First Out)的线性表,简称FIFO.允许插入的一端称为队尾,允许删除的一端 ...
- Android名片扫描识别系统SDK
Android名片扫描识别系统SDK 一.Android名片扫描识别系统应用背景 这些年,随着移动互联的发展,APP应用成爆发式的增长,在很多APP中都涉及到对名片信息的录入,如移动CRM.移动端OA ...
- 你需要了解的 Core Spotlight
你需要了解的 Core Spotlight -- 了解Spotlight Core Spotlight是iOS 9中苹果推出了新的Search API,可以直接搜App内的内容(in-App Sear ...
- WP8.1程序开发中,如何加载本地文件资源或安装在程序包中的资源。
Web 要访问来自 Web 的文件,你可以使用标准的绝对 HTTP URI: <img src="http://www.contoso.com/images/logo.png" ...
- 了解 : angular $filter stateful
{{ abc | myFilter }} angular.module('myStatefulFilterApp', []) .filter('decorate', ['decoration', fu ...