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. Cannot+use+T4+templates+inside+a+.NET+Core+project,NetCore2.0无法使用T4模板解决方法

    Cannot+use+T4+templates+inside+a+.NET+Core+project,NetCore2.0无法使用T4模板解决方法 请见:https://csharp.wekeepco ...

  2. linux进程的管道通信

    linux进程的管道通信 要求 编程实现进程的管道通信,掌握管道通信的同步和互斥机制. 相关函数 pipe管道 指用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件,又名pipe文件.向管 ...

  3. Using Browser Link in Visual Studio 2013

    题记:Browser Link是VS 2013开始引入的一个强大功能,让前端代码(比如AngularJS的代码)在VS中的修改更加轻而易举. 前 端代码是运行在浏览器中,而Visual Studio通 ...

  4. apt-get update 时的问题 W:Failed to fetch gzip:/var/lib/apt/lists/partial...解决办法

    http://askubuntu.com/questions/149454/upgrade-from-11-04-to-11-10-getting-wfailed-to-fetch-gzip 这个问题 ...

  5. 正确设置-Dfile.encoding参数

    正确设置-Dfile.encoding参数 摘自:https://blog.csdn.net/youge/article/details/6178265 2011年02月11日 10:18:00 阅读 ...

  6. CodeBlocks调试功能(转)

    转自:迂者-贺利坚 http://blog.csdn.net/sxhelijian/article/details/15026159 示例代码: #include <iostream> u ...

  7. Jmeter跨线程组调用token

    BeanShell PostProcessor使用 1.正则提取token后添加:后置处理器-->BeanShell PostProcessor 2.BeanShell PostProcesso ...

  8. struts2 、mybatis 、easyui 分页

    rows page 控件自动提交这两个参数 pageSize number The page size. 10pageNumber number Show the page number when p ...

  9. ios7适配--navgationbar遮住下面view的处理

    3down votefavorite   Have you guys stumbled up on this issue ? Basically in iOS 7 Navigation Control ...

  10. 快速入手Web幻灯片制作

    在线幻灯片 使用markdown可以快速的写出优美的文档,接下来我介绍一些简单的语法,快速的用浏览器制作幻灯片. 最基本使用格式 <!DOCTYPE html> <html> ...