题意:
对于一颗树,两种操作(1)修改某边权(2)查询两点间最大边权
解:树链剖分
代码(200ms):
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<ctime>
#include<queue>
#define For(i,j,k) for(register int i=(j);i<=(int)k;i++)
#define Forr(i,j,k) for(register int i=(j);i>=(int)k;i--)
#define Rep(i,u) for(register int i=Begin[(u)],v=to[i];i;i=Next[i],v=to[i])
#define Set(a,b) memset((a),b,sizeof(a))
using namespace std;
const int N=10010,E=20010;
int Begin[N],Next[E],to[E],fa[N],siz[N],son[N],dep[N],w[N],e=1,top[N],cnt,n;
int d[N][3];
void read(int &x){
x=0;char c=getchar();int f(0);
while(c<'0'||c>'9'){c=getchar();if(c=='-')f=1;}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();if(f)x=-x;
}
inline void add(int x,int y){to[++e]=y,Next[e]=Begin[x],Begin[x]=e;}
struct zkwtree{
int T[N<<2],M;
inline void clear(){Set(T,0);}
inline void pushup(int x){T[x]=max(T[x<<1],T[x<<1|1]);}
void Build(){for(M=1;M<=n+1;M<<=1);}
void add(int x,int v){for(T[x+=M]=v,x>>=1;x;x>>=1)pushup(x);}
int query(int s,int t){
int ret=-0x3f3f3f3f;
for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){
if(~s&1)ret=max(ret,T[s^1]);
if(t&1)ret=max(ret,T[t^1]);
}
return ret;
}
}t;
void dfs1(int u,int d){
siz[u]=1;dep[u]=d;
Rep(i,u)
if(fa[u]!=v){
fa[v]=u,dfs1(v,d+1),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp,w[u]=++cnt;
if(son[u])dfs2(son[u],top[u]);
Rep(i,u)
if(son[u]!=v&&fa[u]!=v)
dfs2(v,v);
}
void init(){
read(n);
Set(son,0),Set(Begin,0),Set(fa,0),e=1,cnt=0;
For(i,1,n-1){
read(d[i][0]),read(d[i][1]),read(d[i][2]);
add(d[i][0],d[i][1]),add(d[i][1],d[i][0]);
}
dfs1(1,1);dfs2(1,1);
t.clear();
t.Build();
For(i,1,n-1){
if(dep[d[i][0]]>dep[d[i][1]])swap(d[i][0],d[i][1]);
t.add(w[d[i][1]],d[i][2]);
}
}
int Max(int x,int y){
int tmp=-0x3f3f3f3f;
for(;top[x]!=top[y];){
if(dep[top[x]]<dep[top[y]])swap(x,y);
tmp=max(tmp,t.query(w[top[x]],w[x]));
x=fa[top[x]];
}
if (x==y)return tmp;
if (dep[x]>dep[y])swap(x,y);
return max(tmp,t.query(w[x]+1,w[y]));
}
void solve(){
char s[10];
while(scanf("%s",s)!=EOF){
int x,y;
if (s[0]=='D')break;
read(x),read(y);
if (s[0]!='Q')t.add(w[d[x][1]],y);
else printf("%d\n",Max(x,y));
}
}
int main(){
int _;
for(read(_);_;_--){
init();
solve();
}
return 0;
}