欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - SPOJ-QTREE
题意概括
给你一颗树,每两点之间有权值,然后改变一些权值,问一条路径上的最大值。
题解
树链剖分裸题。
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
const int N=10005;
struct Edge{
int cnt,y[N*2],z[N*2],nxt[N*2],fst[N];
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void add(int a,int b,int c){
y[++cnt]=b,z[cnt]=c,nxt[cnt]=fst[a],fst[a]=cnt;
}
}g;
struct edge{
int a,b,c;
}e[N];
int T,n,pos;
int fa[N],fadis[N],size[N],depth[N],son[N],top[N],p[N],ap[N];
int maxv[N*4];
void Get_Gen_Info(int rt,int pre,int d){
depth[rt]=d,fa[rt]=pre,size[rt]=1,son[rt]=-1;
for (int i=g.fst[rt];i;i=g.nxt[i])
if (g.y[i]!=pre){
int s=g.y[i];
fadis[s]=g.z[i];
Get_Gen_Info(s,rt,d+1);
size[rt]+=size[s];
if (son[rt]==-1||size[s]>size[son[rt]])
son[rt]=s;
}
}
void Get_Pos(int rt,int tp){
top[rt]=tp;
if (son[rt]==-1){
p[rt]=++pos,ap[pos]=rt;
return;
}
else {
p[rt]=++pos,ap[pos]=rt;
Get_Pos(son[rt],tp);
}
for (int i=g.fst[rt];i;i=g.nxt[i]){
int s=g.y[i];
if (s!=fa[rt]&&s!=son[rt])
Get_Pos(s,s);
}
}
void pushup(int rt){
maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);
}
void build(int rt,int le,int ri){
if (le==ri){
maxv[rt]=fadis[ap[le]];
return;
}
int mid=(le+ri)>>1;
build(rt<<1,le,mid);
build(rt<<1|1,mid+1,ri);
pushup(rt);
}
void change(int rt,int le,int ri,int pos,int v){
if (le==ri){
maxv[rt]=v;
return;
}
int mid=(le+ri)>>1;
if (pos<=mid)
change(rt<<1,le,mid,pos,v);
else
change(rt<<1|1,mid+1,ri,pos,v);
pushup(rt);
}
int query(int rt,int le,int ri,int xle,int xri){
if (ri<xle||le>xri)
return 0;
if (xle<=le&&ri<=xri)
return maxv[rt];
int mid=(le+ri)>>1;
return max(query(rt<<1,le,mid,xle,xri),query(rt<<1|1,mid+1,ri,xle,xri));
}
int find(int a,int b){
int f1=top[a],f2=top[b],ans=0;
while (f1!=f2){
if (depth[f1]<depth[f2])
swap(f1,f2),swap(a,b);
ans=max(ans,query(1,1,n,p[f1],p[a]));
a=fa[f1],f1=top[a];
}
if (a==b)
return ans;
if (depth[a]>depth[b])
swap(a,b);
return max(ans,query(1,1,n,p[son[a]],p[b]));
}
int main(){
scanf("%d",&T);
while (T--){
g.clear();
scanf("%d",&n);
for (int i=1,a,b,c;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
e[i].a=a,e[i].b=b,e[i].c=c;
g.add(a,b,c);
g.add(b,a,c);
}
pos=0,fadis[1]=0;
Get_Gen_Info(1,0,0);
Get_Pos(1,1);
for (int i=1;i<n;i++)
if (depth[e[i].a]>depth[e[i].b])
swap(e[i].a,e[i].b);
build(1,1,n);
char str[10];
while (scanf("%s",str)){
if (str[0]=='D')
break;
int a,b;
scanf("%d%d",&a,&b);
if (str[0]=='Q')
printf("%d\n",find(a,b));
else
change(1,1,n,p[e[a].b],b);
}
}
return 0;
}