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. POJ1039几何

    这道题目要求我们判断光线进入一条管道后可以抵达的最大的x坐标. 这是我做的第一道几何题目,卡了我半天.翻了不少书,才大概明白了些.既然是第一次做,就把所有今天学到的就全部写下好了. 1.如何判断平面上 ...

  2. linux加入windows域之完美方案

    运行setup工具 认证配置 选择: “use winbind” “use kerberos” “use winbind authertication” 改为: 删除admin server 其余的改 ...

  3. NFA/DFA算法

    1.问题概述 随着计算机语言的结构越来越复杂,为了开发优秀的编译器,人们已经渐渐感到将词 法分析独立出来做研究的重要性.不过词法分析器的作用却不限于此.回想一下我们的老师刚刚开始向我们讲述程序设计的时 ...

  4. 刷题向》POJ2823 单调队列裸题(<不会做,请自裁>系列)

    最近BZOJ炸了,而我的博客上又更新了一些基本知识,所以这里刷一些裸题,用以丰富知识性博客 POJ2823   滑动的窗口 这是一道经典的单调队题,我记得我刚学的时候就是用这道题作为单调队列的例题,算 ...

  5. 434. Number of Segments in a String 字符串中的单词个数

    [抄题]: Count the number of segments in a string, where a segment is defined to be a contiguous sequen ...

  6. Android 单例模式探讨

    Singleton模式可以是很简单的,它的全部只需要一个类就可以完成(看看这章可怜的UML图).但是如果在“对象创建的次数以及何时被创建”这两点上较真起来,Singleton模式可以相当的复杂,比头五 ...

  7. MagicNotes:突破来自外界的脑力压制

    MagicNotes,思绪随风飞扬,偶尔在这里停留. 在前面的<MagicNotes:如何迈向工作的坦途>里面,我们提到了在工作中应该发挥好个人的主观能动性,简单来说就是要学会主动出击.但 ...

  8. 【原创】请不要对Boost Format使用Byte作为参数

    曾几何时我们可以肆无忌惮的对sprintf传入BYTE等类型作为参数,只要你指定的为%D即可打印出对应的数字 但是boost format不可以,当你发生类型截断,错误,异常,请尽快查看你传入的类型是 ...

  9. (函数分治法)实现pow函数(x的y次方幂)

    题目:实现pow函数. 题目分析:因为一个一个乘,循环太大,参考矩阵连乘问题:对于n=4的话,可以得出x的平方,然后平方与平方相乘.节省计算次数.对于偶数的幂,只要x的平方多次递归调用即可:对于奇数的 ...

  10. 综合学生信息管理系统(JSP+JDBC)

    原创 通过JSP+JDBC制作一个简单的操作数据库中表信息的系统. 总体界面如下,一共有5个功能块. 功能一:列出全部学生 功能二:按条件查询学生 功能三:新添加学生 功能四:按条件删除学生 功能五: ...