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. spring boot druid mybatis多数据源

    一.关闭数据源自动配置(很关键) @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) 如果不关闭会报异常:o ...

  2. AJPFX简述Scanner类的特点

    hasNextInt() :判断是否还有下一个输入项,其中Xxx可以是Int,Double等.如果需要判断是否包含下一个字符串,则可以省略Xxx        nextInt(): 获取下一个输入项. ...

  3. JVM内存各个区域分工简单介绍

    JVM内存各个区域简单介绍: 程序计数器:程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器. 在使用多线程时,为了线程切换后能恢复到正确的执行位置,每条线程都需要有个独立 ...

  4. ES6学习笔记(9)----Symbol

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ Symbol1.symbol:Symbol是javascript的第七种原始数据类型,代表独一无 ...

  5. python中 import 和from ... import 的区别

    先看一个例子: 我自定义的一个moudle,里面有一个方法sayhi,还有一个变量version#!/usr/bin/env python # coding=utf-8 # Filename: mym ...

  6. 简单修改BOOK主题样式

    body{ font-size: 13px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; margin: 0px; word ...

  7. docker 新手入门(docker的安装)

    docker的安装(在centos7下面) 1. 卸载在liunx下,先看有没有安装docker,docker version,如果有的话,可以先移除 yum remove ........ 可以使用 ...

  8. win10下安装使用mysql-5.7.23-winx64

    下载MySQLhttps://dev.mysql.com/downloads/file/?id=478884 解压到文件,此例为D盘根目录 在mysql-5.7.23-winx64目录下创建[my.i ...

  9. 指针-AC自动机

    大家都不喜欢指针,但是这个AC自动机仿佛不用不行…… 先引用我最喜欢的话:“AC自动机,不是自动AC的机器.” 如果写不好还可能一直WA AC自动机是KMP与Trie树的完美结合,适用于多字符串匹配, ...

  10. matlab 随笔

    <<matlab高级编程技巧与应用:45个案例分析>> 一. 重新认识向量化编程 1.向量化编程与循环的比较 2.预分配内存更好 3.matlab中是列优先 4.归一化 数据归 ...