# SPOJ 375 树链剖分

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 22222
char ch[11];
int n,cases,root,tree[N*4],xx,yy,ans;
int tot,first[N],next[N],v[N],w[N];
int cnt,top[N],deep[N],size[N],son[N],rec[N],f[N];
struct Edge{int from,to,weight;}edge[N];
w[tot]=z,v[tot]=y;
next[tot]=first[x],first[x]=tot++;
}
void dfs(int x,int fa){
size[x]=1;son[x]=0;
for(int i=first[x];~i;i=next[i]){
if(v[i]==fa)continue;
f[v[i]]=x;
deep[v[i]]=deep[x]+1;
dfs(v[i],x);
size[x]+=size[v[i]];
if(size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int fa,int tp){
rec[x]=++cnt;top[x]=tp;
if(son[x])dfs2(son[x],x,tp);
for(int i=first[x];~i;i=next[i])
if(v[i]!=son[x]&&v[i]!=fa)dfs2(v[i],x,v[i]);
}
void insert(int l,int r,int pos){
if(l==r){tree[pos]=yy;return;}
int mid=(l+r)>>1;
if(mid<xx)insert(mid+1,r,pos<<1|1);
else insert(l,mid,pos<<1);
tree[pos]=max(tree[pos<<1],tree[pos<<1|1]);
}
int query(int l,int r,int pos,int Left,int Right){
if(l>=Left&&r<=Right)return tree[pos];
int mid=(l+r)>>1;
if(mid<Left)return query(mid+1,r,pos<<1|1,Left,Right);
else if(mid>=Right)return query(l,mid,pos<<1,Left,Right);
else return max(query(l,mid,pos<<1,Left,Right),query(mid+1,r,pos<<1|1,Left,Right));
}
void find(){
int fx=top[xx],fy=top[yy];
while(fx!=fy){
if(deep[fx]<deep[fy])swap(xx,yy),swap(fx,fy);
ans=max(ans,query(1,n,1,rec[fx],rec[xx]));
xx=f[fx];fx=top[xx];
}
if(xx==yy)return;
if(deep[xx]>deep[yy])swap(xx,yy);
ans=max(ans,query(1,n,1,rec[son[xx]],rec[yy]));
}
int main(){
scanf("%d",&cases);
while(cases--){
memset(tree,0,sizeof(tree));
memset(size,0,sizeof(size));
memset(first,-1,sizeof(first));
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].weight);
}
root=(n+1)>>1;
f[root]=deep[root]=cnt=tot=0;
dfs(root,root),dfs2(root,root,root);
for(int i=1;i<n;i++){
if(deep[edge[i].from]>deep[edge[i].to])swap(edge[i].from,edge[i].to);
xx=rec[edge[i].to],yy=edge[i].weight;
insert(1,cnt,1);
}
while(scanf("%s",ch)&&ch[0]!='D'){
scanf("%d%d",&xx,&yy);
if(ch[0]=='Q')ans=0,find(),printf("%d\n",ans);
else xx=rec[edge[xx].to],insert(1,n,1);
}
}
}


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

## SPOJ375(树链剖分)

• ACdreamers
• 2013年08月30日 20:20
• 2645

## SPOJ375——Query on a tree（树链剖分模板详解以及入门）

You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
• say_c_box
• 2016年08月05日 10:42
• 1510

## 【转】SPOJ 375 树链剖分

• chm517
• 2014年04月09日 19:53
• 300

## spoj 375 （树链剖分）

spoj 375 题目：http://www.spoj.com/problems/QTREE/ 题目大意：给你一棵有N个结点的树，执行两种操作：（1）CHANGE a b，把某一条树枝上的权值改为b。...
• u010794465
• 2013年07月21日 14:14
• 694

## SPOJ 375 树链剖分学习

• u014610830
• 2015年09月01日 23:07
• 248

## SPOJ 375 (树链剖分+线段树)

“在一棵树上进行路径的修改、求极值、求和”乍一看只要线段树就能轻松解决，实际上，仅凭线段树是不能搞定它的。我们需要用到一种貌似高级的复杂算法——树链剖分。     树链，就是树上的路径。剖分，就...
• pi9nc
• 2013年10月08日 11:11
• 2990

## spoj 375 树链剖分模板

/* 只是一道树链刨分的入门题,作为模板用。 */ #include #include #include #include #include #include #include using names...
• u011483306
• 2014年09月29日 15:52
• 392

## Spoj 375 QTREE（树链剖分）

Description You are given a tree (an acyclic undirected connected graph) with N nodes, and edge...
• u014258433
• 2016年08月22日 23:56
• 144

## SPOJ 375 树链剖分

SPOJ 375 题目链接： 题意： 思路： 首先感谢这位博主http://blog.csdn.net/y990041769/article/details/40348013，基本照着打的。 ...
• beihai2013
• 2015年11月05日 20:43
• 166

## LCT spoj 375 树链剖分

• rabbit_fjq_dick
• 2017年04月11日 15:27
• 95

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