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)的更多相关文章

  1. Cogs 1672. [SPOJ375 QTREE]难存的情缘 LCT,树链剖分,填坑计划

    题目:http://cojs.tk/cogs/problem/problem.php?pid=1672 1672. [SPOJ375 QTREE]难存的情缘 ★★★☆   输入文件:qtree.in  ...

  2. SPOJ375.QTREE树链剖分

    题意:一个树,a b c 代表a--b边的权值为c.CHANGE x y  把输入的第x条边的权值改为y,QUERY x y 查询x--y路径上边的权值的最大值. 第一次写树链剖分,其实树链剖分只能说 ...

  3. [SPOJ375]QTREE - Query on a tree【树链剖分】

    题目描述 给你一棵树,两种操作. 修改边权,查找边权的最大值. 分析 我们都知道,树链剖分能够维护点权. 而且每一条边只有一个,且唯一对应一个儿子节点,那么就把信息放到这个儿子节点上. 注意,lca的 ...

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

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

  5. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

  6. 树链剖分边权模板spoj375

    树链剖分是树分解成多条链来解决树上两点之间的路径上的问题 如何求出树链:第一次dfs求出树上每个结点的大小和深度和最大的儿子,第二次dfs就能将最大的儿子串起来并hash(映射)到线段树上(或者其他数 ...

  7. 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 ...

  8. 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, ...

  9. SPOJ QTree【树链剖分】

    一 题目 QTREE 二 分析 第一道树链剖分的题,写的好艰难啊. 题意还是比较好理解的,就是在树上操作. 对于修改,题中要求的是单点修改,就算是直接树上操作也是非常简单的. 对于查询,查询的时候,是 ...

随机推荐

  1. Go并发编程实践

    前言 并发编程一直是Golang区别与其他语言的很大优势,也是实际工作场景中经常遇到的.近日笔者在组内分享了我们常见的并发场景,及代码示例,以期望大家能在遇到相同场景下,能快速的想到解决方案,或者是拿 ...

  2. Salesforce删除数据时出现Insufficient privileges的可能原因

    遇到一个诡异的情况,用户通过界面删除一条自定义Object的数据的时候出现了Insufficient privileges.按理说,如果用户的Profile没有此Object的删除权限的话,应该连删除 ...

  3. .bat文件设置IP、DNS

    这几天遇到个烦心事,每次开机之后都要去手动去设置一下IP地址,一大串的数字还是有点麻烦,于是就想写个批处理文件设置IP 注意:在DOS下设置IP时需要管理员权限运行 1.查看机子设置IP需要用到的名字 ...

  4. 重写titleView

    在一些特定的情况下不能使用原有的titleView需要重写titleView代码如下 #import "TitleView.h" @implementation TitleView ...

  5. Storyboard 自定义转场动画

    在storyboard中,segue有几种不同的类型,在iphone和ipad的开发中,segue的类型是不同的.在iphone中,segue 有:push,modal,和custom三种不同的类型, ...

  6. 在windows搭建react-native android 开发环境总结

    1.安装必须的软件 1.Python 2    注意勾选 Add python.exe to Path,选项,这样就可以在安装完成后,不用手动去添加环境变量    安装完,打开cmd.exe,输入py ...

  7. Android项目实战(三十一):异步下载apk文件并安装(非静默安装)

    前言: 实现异步下载apk文件 并 安装.(进度条对话框显示下载进度的展现方式) 涉及技术点: 1.ProgressDialog   进度条对话框  用于显示下载进度 2.AsyncTask     ...

  8. Animate自定义动画

    在jQuery中出了基本的动画之外,还有用户 可以自定义的函数,Animate() 用于创建自定义动画的函数. apI上指出: 这个函数的关键在于指定动画形式及结果样式属性对象.这个对象中每个属性都表 ...

  9. Linux下ls命令显示符号链接权限为777的探索

    Linux下ls命令显示符号链接权限为777的探索 --深入ls.链接.文件系统与权限 一.摘要 ls是Linux和Unix下最常使用的命令之一,主要用来列举目录下的文件信息,-l参数允许查看当前目录 ...

  10. DOM操作表格——HTML DOM

    html创建表格: <table berder='1' width='300'> <thead> <tr> <th>姓名</th> < ...