# SPOJ 375 Query on a tree（初学树链剖分）

## QTREE - Query on a tree

no tags

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


 14620018 2015-07-07 17:10:34 ka Query on a tree accepted 0.44 3.9M C++ 4.9
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define refeach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
using namespace std;
typedef long long ll;

const int N = 1e4+100;
struct Edge
{
int u,v,w,nxt;
Edge(){}
Edge(int u,int v,int w,int nxt) : u(u),v(v),w(w),nxt(nxt) {}
}es[N<<1];
int ecnt;
int n;
inline void add_edge(int u,int v,int w)
{
}

int dep[N],son[N],sz[N],fa[N];
void dfs1(int u)
{
dep[u] = dep[fa[u]]+1;
son[u] = 0,sz[u] = 1;
{
int v = es[i].v;
if(fa[u] == v) continue;
fa[v] = u;
dfs1(v);
sz[u] += sz[v];
if(sz[v] > sz[son[u]]) son[u] = v;
}
}

int tp[N],tid[N];
int indx;
void dfs2(int u,int ance)
{
tid[u] = ++indx;
tp[u] = ance;
if(son[u]) dfs2(son[u],ance);
{
int v = es[i].v;
if(v == fa[u]) continue;
if(v != son[u]) dfs2(v,v);
}
}
#define root 1,indx,1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int maxn[N<<2];
inline void pushup(int rt)
{
maxn[rt] = max(maxn[rt<<1],maxn[rt<<1|1]);
}
void update(int pos,int x,int l,int r,int rt)
{
if(l == r)
{
maxn[rt] = x;
return ;
}
int m = (l+r)>>1;
if(pos <= m) update(pos,x,lson);
else update(pos,x,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R) return maxn[rt];
int maxx = 0;
int m = (l+r)>>1;
if(L <= m) maxx = max(maxx,query(L,R,lson));
if(R >= m+1) maxx = max(maxx,query(L,R,rson));
return maxx;
}

int solve(int u,int v)
{
int anceu = tp[u],ancev = tp[v];
int maxx = 0;
while(anceu != ancev)
{
if(dep[anceu] < dep[ancev]) swap(anceu,ancev),swap(u,v);
maxx = max(maxx,query(tid[anceu],tid[u],root));
u = fa[anceu];
anceu = tp[u];
}
if(u == v) return maxx;
if(dep[u] < dep[v]) return max(maxx,query(tid[son[u]],tid[v],root));
else return max(maxx,query(tid[son[v]],tid[u],root));
}
void ini()
{
indx = ecnt = 0;
memset(maxn,0,sizeof(maxn));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ini();
scanf("%d",&n);
REP(i,n-1)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
}
char op[20];
dfs1(1);
dfs2(1,1);
REP(i,n-1)
{
int u = es[i].u,v = es[i].v , w = es[i].w;
if(dep[v] < dep[u]) swap(es[i].u,es[i].v);
update(tid[es[i].v],w,root);
}
while(scanf("%s",op))
{
if(op[0] == 'D') break;
if(op[0] == 'Q')
{
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",solve(u,v));
}
else
{
int id,x;
scanf("%d%d",&id,&x);
update(tid[es[id].v],x,root);
}
}
}
}


• 本文已收录于以下专栏：

举报原因： 您举报文章：SPOJ 375 Query on a tree（初学树链剖分） 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)