树链剖分 此题是修改边的权值
树链剖分部分 参考http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <stack>
#include <vector>
#include <sstream>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <algorithm>
#include <iostream>
#define FFI freopen("in.txt", "r", stdin)
#define maxn 20010
#define INF 0x3f3f3f3f
#define inf 10000000
#define MOD 1000000007
#define ULL unsigned long long
#define LL long long
#define _setm(houge) memset(houge, INF, sizeof(houge))
#define _setf(houge) memset(houge, -1, sizeof(houge))
#define _clear(houge) memset(houge, 0, sizeof(houge))
using namespace std;
struct node
{
int l;
int r;
int max_val;
int setv;
};
node a[maxn<<2], p;
void pushup(int rt)
{
a[rt].max_val = max(a[rt<<1].max_val, a[rt<<1|1].max_val);
}
void pushdown(int rt)
{
if(a[rt].setv != -1)
{
a[rt<<1].setv = a[rt<<1|1].setv = a[rt].setv;
a[rt<<1].max_val = a[rt<<1|1].max_val = a[rt].setv;
a[rt].setv = -1;
}
}
void build(int l, int r, int rt)
{
a[rt].max_val = 0;
a[rt].setv = -1;
a[rt].l = l;
a[rt].r = r;
if(l == r)
return;
int m = (l + r) >> 1;
build(l, m, rt<<1);
build(m+1, r, rt<<1|1);
}
void update(int x, int y, int rt, int v)
{
if(a[rt].l == x && a[rt].r == y)
{
a[rt].setv = v;
a[rt].max_val = v;
return;
}
pushdown(rt);
int m = (a[rt].l + a[rt].r) >> 1;
if(y <= m)
update(x, y, rt<<1, v);
else if(x > m)
update(x, y, rt<<1|1, v);
else
{
update(x, m, rt<<1, v);
update(m+1, y, rt<<1|1, v);
}
pushup(rt);
}
void query(int x, int y, int rt)
{
if(a[rt].l == x && a[rt].r == y) {
p.max_val = max(p.max_val, a[rt].max_val);
return;
}
pushdown(rt);
int m = (a[rt].l + a[rt].r) >> 1;
if(y <= m)
query(x, y, rt<<1);
else if(x > m)
query(x, y, rt<<1|1);
else {
query(x, m, rt<<1);
query(m+1, y, rt<<1|1);
}
pushup(rt);
}
struct Tedge
{ int b, next; } e[maxn * 2];
int n, z, edge, root;
int d[maxn][3];
int first[maxn], dep[maxn], w[maxn], fa[maxn], top[maxn], son[maxn], siz[maxn];
void insert(int a, int b) {
e[++ edge].b = b;
e[edge].next = first[a];
first[a] = edge;
}
void dfs(int v) {
siz[v] = 1, son[v] = 0;
for(int i = first[v]; i > 0; i = e[i].next) {
if(e[i].b != fa[v]) {
fa[e[i].b] = v;
dep[e[i].b] = dep[v]+1;
dfs(e[i].b);
if(siz[e[i].b] > siz[son[v]]) son[v] = e[i].b;
siz[v] += siz[e[i].b];
}
}
}
void build_tree(int v, int tp) {
w[v] = ++ z, top[v] = tp;
if(son[v] != 0) build_tree(son[v], tp);
for(int i = first[v]; i > 0; i = e[i].next) {
if(e[i].b != fa[v] && e[i].b != son[v])
build_tree(e[i].b, e[i].b);
}
}
int _find(int va, int vb)
{
int f1 = top[va], f2 = top[vb], tmp = 0;
while (f1 != f2) {
if(dep[f1] < dep[f2]) {
swap(f1, f2);
swap(va, vb);
}
p.max_val = 0;
query(w[f1], w[va], 1);
tmp = max(tmp, p.max_val);
va = fa[f1];
f1 = top[va];
}
if(va == vb) return tmp;
if(dep[va] > dep[vb]) swap(va, vb);
p.max_val = 0;
query(w[son[va]], w[vb], 1);
return max(tmp, p.max_val);
}
int main()
{
int t;
scanf("%d", &t);
while(t --) {
scanf("%d", &n);
root = (n+1)/2;
fa[root] = z = dep[root] = edge = 0;
_clear(siz);
_clear(first);
for(int i = 1; i < n; ++ i) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
d[i][0] = a, d[i][1] = b, d[i][2] = c;
insert(a, b);
insert(b, a);
}
dfs(root);
build_tree(root, root);
//puts("121");
build(1, z, 1);
for(int i = 1; i < n; ++ i) {
if (dep[d[i][0]] > dep[d[i][1]]) swap(d[i][0], d[i][1]);
update(w[d[i][1]], w[d[i][1]], 1, d[i][2]);
}
char s[10];
while(scanf("%s", s) == 1 && s[0] != 'D') {
int a, b;
scanf("%d%d", &a, &b);
if(s[0] == 'Q') {
printf("%d\n", _find(a, b));
}
else {
update(w[d[a][1]], w[d[a][1]], 1, b);
}
}
}
return 0;
}