Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu

Submit Status

Description

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 ab 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
 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct edge{
int u,v,w,next;
}e[];
struct node{
int l,r,val;
node *lc,*rc;
}*root=NULL;
int t,n,m,head[],js,p;
int fa[],son[],dep[],top[],pos[],siz[];
// fa存他的父亲 son存他的重孩子 dep它的深度 top他所在重链的链顶
//pos在线段树中的位置 siz[v]以v为顶的子树的孩子数
void memsett()
{
js=;p=;
memset(head,,sizeof(head));
memset(e,,sizeof(e));
memset(son,,sizeof(son));
}
void add_edge(int u,int v,int w)
{
e[++js].u=u;e[js].v=v;e[js].w=w;
e[js].next=head[u];head[u]=js;
}
void dfs(int u,int f,int d)
{
fa[u]=f;dep[u]=d;siz[u]=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=f)
{
dfs(v,u,d+);
siz[u]+=siz[v];
if(!son[u]||siz[son[u]]<siz[v])
son[u]=v;
}
}
}
void gettop(int u,int tp)
{
top[u]=tp;pos[u]=++p;
if(!son[u]) return;
gettop(son[u],tp);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=son[u]&&v!=fa[u])
gettop(v,v);
}
}
void build(node * &pt,int l,int r)
{
pt=new(node);
pt->l=l;pt->r=r;pt->val=;
if(l==r)
{
pt->lc=pt->rc=NULL;
return ;
}
int mid=(l+r)/;
build(pt->lc,l,mid);
build(pt->rc,mid+,r);
}
void update(node * p,int ps,int val)
{
if(p->l==p->r)
{
p->val=val;return;
}
int mid=(p->l+p->r)/;
if(ps<=mid) update(p->lc,ps,val);
else update(p->rc,ps,val);
p->val=max(p->lc->val,p->rc->val);
}
int query(node * p,int l,int r)
{
if(l<=p->l&&p->r<=r)return p->val;
int mid=(p->l+p->r)/;
int ans=;
if(l<=mid)ans=max(ans,query(p->lc,l,r));
if(r>mid)ans=max(ans,query(p->rc,l,r));
return ans;
}
int find(int u,int v)
{
int tp1=top[u],tp2=top[v],ans=;
while(tp1!=tp2)
{
if(dep[tp1]<dep[tp2])
{
swap(tp1,tp2);swap(u,v);
}
ans=max(ans,query(root,pos[tp1],pos[u]));
u=fa[tp1];tp1=top[u];
}
if(u==v) return ans;
if(dep[u]>dep[v]) swap(u,v);
return max(ans,query(root,pos[u]+,pos[v]));
}
int main()
{
scanf("%d",&t);
while(t--)
{
memsett();
scanf("%d",&n);
for(int i=;i<=n-;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);add_edge(y,x,z);
}
dfs(,,);
gettop(,);
build(root,,p);
for(int i=;i<*n-;i+=)// 建边表时见了两遍
{
if(dep[e[i].v]<dep[e[i].u]) swap(e[i].v,e[i].u);// 让v在下面
update(root,pos[e[i].v],e[i].w);
}
char s[];int u,v;
while(scanf("%s",s)==)
{
if(s[]=='D') break;
scanf("%d%d",&u,&v);
if(s[]=='Q') printf("%d\n",find(u,v));// 查询从u到v所经过的最大边权
else update(root,pos[e[u*-].v],v);// 将第u条边的权值修改为v
}
}
return ;
}
思路:树链剖分基础题

SPOJ VJudge QTREE - Query on a tree的更多相关文章

  1. spoj 375 QTREE - Query on a tree 树链剖分

    题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...

  2. SPOJ 375 QTREE - Query on a tree

    思路 注意本题只能用C,不能用C++ 其他的都和上一题一样 代码 #include <stdio.h> #include <string.h> #define MAXN 100 ...

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

  4. QTREE - Query on a tree

    QTREE - Query on a tree 题目链接:http://www.spoj.com/problems/QTREE/ 参考博客:http://blog.sina.com.cn/s/blog ...

  5. SP375 QTREE - Query on a tree (树剖)

    题目 SP375 QTREE - Query on a tree 解析 也就是个蓝题,因为比较长 树剖裸题(基本上),单点修改,链上查询. 顺便来说一下链上操作时如何将边上的操作转化为点上的操作: 可 ...

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

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

  7. SPOJ QTREE Query on a tree ——树链剖分 线段树

    [题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...

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

    题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...

  9. SPOJ QTREE Query on a tree VI

    You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...

随机推荐

  1. 2019/05/11 JAVA虚拟机原理堆、栈、方法区概念区别

    Java堆 堆内存用于存放由new创建的对象和数组.在堆中分配的内存,由java虚拟机自动垃圾回收器来管理.在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对 ...

  2. AJPFX的内存管理小结

    管理范围:任何继承于 NSObject的对象原理:每一个对象都有引用计数器当使用alloc new 和 copy创建对象时引用计数器被设置为1给对象发送一条retain消息 ,引用计数器加1     ...

  3. unity内存管理

    最近一直在研究unity的内存加载,因为它是游戏运行的重中之重,如果不深入理解和合理运用,很可能导致项目因内存太大而崩溃. 详细说一下细节概念:AssetBundle运行时加载:来自文件就用Creat ...

  4. poj2677 Tour

    题意: 双调欧几里得旅行商问题. 思路: dp.定义dp[i][j](i <= j)为从点j从右向左严格按照x坐标递减顺序走到点1,之后再从点1从左向右严格按照x坐标递增的顺序走到点i,并且在此 ...

  5. android开发工具eclipse的安装与配置

    l开发主要应用Eclipse 3.7版本. l辅助工具为jdk.Androidsdk Android环境搭建   –1.1.JDK安装 –1.2.Eclipse安装 –1.3.Android SDK安 ...

  6. Oracle的数据伪列(ROWNUM)

    作者:Vashon 时间:20150414 数据库:Oracle11g 数据伪列(ROWNUM) *范例:查询前5条记录:select rownum,empno,job,hiredate,sal fr ...

  7. 初探ABP--记一些常见的开发问题

    1.Update-Database : 无法将“Update-Database”项识别为 cmdlet.函数.脚本文件或可运行程序的名称.请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次. ...

  8. 回顾Spring MVC_01_概述_入门案例

    SpringMVC: SpringMVC是Spring为展现层提供的基于MVC设计的优秀的Web框架,是目前最主流的MVC框架之一 SpringMVC通过注解,让POJO成为处理请求的控制器,而无须实 ...

  9. Android Studio -自定义LogCat的颜色

    博文地址 http://www.cnblogs.com/Loonger/p/6285344.html 先看看效果 (设置中的显示,下图) 步骤如下 File->Settings 或Ctrl + ...

  10. uva1336 Fixing the Great Wall

    用到了kase避免memset超时 #include<cstdio> #include<cstring> #include<cmath> #include<a ...