基础的树链剖分题目,不过是边权,可以向下映射成点权或者按边剖分。
VIEW CODE
#include <iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<algorithm>
#include<string>
using namespace std;
const int mmax=10010;
const int inf=0x3fffffff;
struct edge
{
int st,en,cost;
int next;
}E[2*mmax];
int p[mmax],fa[mmax],son[mmax],top[mmax],ID[mmax];
int deep[mmax],cost[mmax],id_[mmax];
bool vis[mmax];
int num;
void add(int st,int en,int cost)
{
E[num].st=st;
E[num].en=en;
E[num].cost=cost;
E[num].next=p[st];
p[st]=num++;
}
void init()
{
memset(p,-1,sizeof p);
num=0;
}
struct tree
{
int l,r;
int max_n;
int mid()
{
return (l+r)>>1;
}
}T[4*mmax];
void build(int id,int l,int r)
{
T[id].l=l,T[id].r=r;
if(l==r)
{
T[id].max_n=cost[ID[l]];
return ;
}
int mid=T[id].mid();
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
T[id].max_n=max(T[id<<1].max_n,T[id<<1|1].max_n);
}
void updata(int id,int pos,int val)
{
if(T[id].l==T[id].r)
{
T[id].max_n=val;
return ;
}
int mid=T[id].mid();
if(mid>=pos)
updata(id<<1,pos,val);
else
updata(id<<1|1,pos,val);
T[id].max_n=max(T[id<<1].max_n,T[id<<1|1].max_n);
}
int query(int id,int l,int r)
{
if(l<=T[id].l&&T[id].r<=r)
return T[id].max_n;
int mid=T[id].mid();
int ans=0;
if(mid>=l)
ans=max(ans,query(id<<1,l,r));
if(mid<r)
ans=max(ans,query(id<<1|1,l,r));
return ans;
}
int dfs(int u)
{
vis[u]=1;
int cnt=1,tmp=0,e=0,Co=inf;
for(int i=p[u];i+1;i=E[i].next)
{
int v=E[i].en;
int len=E[i].cost;
if(!vis[v])
{
fa[v]=u;
deep[v]=deep[u]+1;
cost[v]=len;
int tt=dfs(v);
cnt+=tt;
if(tmp<tt)
{
tmp=tt;
e=v;
Co=len;
}
}
}
son[u]=e;
return cnt;
}
int now_cnt;
void new_id(int u)
{
ID[now_cnt]=u;
id_[u]=now_cnt;
now_cnt++;
vis[u]=1;
if(son[u])
{
top[son[u]]=top[u];
new_id(son[u]);
}
for(int i=p[u];i+1;i=E[i].next)
{
int v=E[i].en;
if(!vis[v])
new_id(v);
}
}
int solve(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])
swap(x,y);
ans=max(ans,query(1,id_[top[x]],id_[x]));
x=fa[top[x]];
}
if(x!=y)
{
if(deep[x]>deep[y])
swap(x,y);
ans=max(ans,query(1,id_[son[x]],id_[y]));
}
return ans;
}
char str[20];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d",&n);
for(int i=0;i<n-1;i++)
{
int u,v,cost;
scanf("%d %d %d",&u,&v,&cost);
add(u,v,cost);
add(v,u,cost);
}
fa[1]=1;
deep[1]=0;
cost[1]=0;
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++)
top[i]=i;
dfs(1);
memset(vis,0,sizeof vis);
now_cnt=1;
new_id(1);
// for(int i=1;i<=n;i++)
// cout<<son[i]<<" ";
// cout<<endl;
// system("pause");
build(1,1,n);
while(1)
{
int a,b;
scanf("%s",str);
if(!strcmp(str,"DONE"))
break;
scanf("%d %d",&a,&b);
if(!strcmp(str,"QUERY"))
printf("%d\n",solve(a,b));
if(!strcmp(str,"CHANGE"))
{
int st=E[2*a-2].st;
int en=E[2*a-2].en;
if(deep[st]>deep[en])
swap(st,en);
updata(1,id_[en],b);
}
}
//system("pause");
}
return 0;
}