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
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 100005
#define inf 0x7fffffff
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
#define mclr(x,a) memset((x),a,sizeof(x))
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-5
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii; inline int rd() {
int x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
} ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
int sqr(int x) { return x * x; } /*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1; y = 0; return a;
}
ans = exgcd(b, a%b, x, y);
ll t = x; x = y; y = t - a / b * y;
return ans;
}
*/
struct node {
int to, nxt;
}e[maxn];
int head[maxn], tot;
int top[maxn];// top[v]表示v所在的重链的顶点
int fa[maxn];
int dep[maxn];
int num[maxn];// num[v]表示以v为根的子树大小
int p[maxn];// p[v]表示v与其父亲节点在线段树的位置
int fp[maxn];
int son[maxn];// 重儿子
int pos;
int n; void init() {
tot = 0; memset(head, -1, sizeof(head));
pos = 1; memset(son, -1, sizeof(son));
}
void addedge(int u, int v) {
e[tot].to = v; e[tot].nxt = head[u]; head[u] = tot++;
} void dfs1(int u, int pre, int d) {
dep[u] = d; fa[u] = pre; num[u] = 1;
for (int i = head[u]; i != -1; i = e[i].nxt) {
int v = e[i].to;
if (v != pre) {
dfs1(v, u, d + 1);
num[u] += num[v];
if (son[u] == -1 || num[v] > num[son[u]])son[u] = v;
}
}
} void dfs2(int u, int sp) {
top[u] = sp;
if (son[u] != -1) {
p[u] = pos++;
fp[p[u]] = u;
dfs2(son[u], sp);
}
else {
p[u] = pos++; fp[p[u]] = u; return;
}
for (int i = head[u]; i != -1; i = e[i].nxt) {
int v = e[i].to;
if (v != son[u] && v != fa[u])dfs2(v, v);
}
} #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int maxx[maxn];
int val[maxn];
void pushup(int rt) {
maxx[rt] = max(maxx[rt << 1], maxx[rt << 1 | 1]);
}
void build(int l, int r, int rt) {
if (l == r) {
maxx[rt] = val[l]; return;
}
int m = (l + r) >> 1;
build(lson); build(rson); pushup(rt);
}
void upd(int p, int x, int l, int r, int rt) {
if (l == r) {
maxx[rt] = x; return;
}
int m = (l + r) >> 1;
if (p <= m)upd(p, x, lson);
else upd(p, x, rson);
pushup(rt);
}
int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return maxx[rt];
}
int m = (l + r) >> 1;
int ans = 0;
if (L <= m)ans = max(ans, query(L, R, lson));
if (m < R)ans = max(ans, query(L, R, rson));
return ans;
} int Find(int u, int v) {
int f1 = top[u], f2 = top[v];
int tmp = 0;
while (f1 != f2) {
if (dep[f1] < dep[f2]) {
swap(f1, f2); swap(u, v);
}
tmp = max(tmp, query(p[f1], p[u], 1, n, 1));
u = fa[f1]; f1 = top[u];
}
if (u == v)return tmp;
if (dep[u] > dep[v])swap(u, v);
return max(tmp, query(p[son[u]], p[v], 1, n, 1));
}
int ed[maxn][3]; int main()
{
// ios::sync_with_stdio(0);
int t; t = rd();
while (t--) {
init(); n = rd();
// getchar();
for (int i = 0; i < n - 1; i++) {
ed[i][0] = rd(); ed[i][1] = rd(); ed[i][2] = rd();
addedge(ed[i][0], ed[i][1]);
addedge(ed[i][1], ed[i][0]);
}
dfs1(1, 0, 0); dfs2(1, 1);
for (int i = 0; i < n - 1; i++) {
if (dep[ed[i][0]] < dep[ed[i][1]]) {
swap(ed[i][0], ed[i][1]);
}
val[p[ed[i][0]]] = ed[i][2];
}
build(1, n, 1);
char opt[10];
while (scanf("%s",opt)) {
if (opt[0] == 'D')break;
int u, v; u = rd(); v = rd();
if (opt[0] == 'Q') {
printf("%d\n", Find(u, v));
}
else upd(p[ed[u - 1][0]], v, 1, n, 1);
}
}
return 0;
}

Query on a tree 树链剖分 [模板]的更多相关文章

  1. SPOJ 375 Query on a tree 树链剖分模板

    第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...

  2. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

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

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

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

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

  5. SPOJ Query on a tree 树链剖分 水题

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  6. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  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 (树链剖分)

    Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges ...

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

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

随机推荐

  1. VS2008与MATLAB R2007a混合编程配置过程

    系统平台:windows xp sp2, visual studio 2008 professional, matlab R2007a 首先,为了使matlab 能够找到vs2008编译器,需要下载以 ...

  2. java socket发送xml报文

    ServerRun.java import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; pub ...

  3. PHP网站

    1.NetBeans 解决PHP调试问题:https://netbeans.org/ 支持PHP调试的版本 2. http://document.thinkphp.cn/manual_3_2.html ...

  4. git获取网上的项目

    这里是从coding.net上下载项目至本地phpstorm并配置好相关环境. 这里url地址正是项目路径.获取的地方是: 下面那个url直接复制粘贴. 自己选择一个目录,然后clone. 下面便是前 ...

  5. SaeMysql操作示例

    新浪sae的官方说明文档:http://apidoc.sinaapp.com/sae/SaeMysql.html Class SaeMysql 具体实现:http://apidoc.sinaapp.c ...

  6. ROS naviagtion analysis: costmap_2d--Costmap2DROS

    博客转载自:https://blog.csdn.net/u013158492/article/details/50485418 在上一篇文章中moveBase就有关于costmap_2d的使用: pl ...

  7. 38.NOW() 函数

    NOW 函数返回当前的日期和时间. 提示:如果您在使用 Sql Server 数据库,请使用 getdate() 函数来获得当前的日期时间. SQL NOW() 语法 SELECT NOW() FRO ...

  8. Linux系统获取CPU温度

    Linux系统获取CPU温度 摘自:https://jingyan.baidu.com/article/cbf0e500407d072eab289343.html 各位好,本篇将简单介绍如何在不同系列 ...

  9. this与$(this)的区别

    this,表示当前的上下文对象是一个html对象,可以调用html对象所拥有的属性和方法. $(this),代表的上下文对象是一个jquery的上下文对象,可以调用jQuery的方法和属性值.

  10. [GO]切片和底层数组的关系

    package main import "fmt" func main() { a := [], , , , , , , , , } s1 := a[:] s1[] = fmt.P ...