http://www.spoj.pl/problems/QTREE/
给一颗树,每条边有一个权值。有两种操作:1、修改某条边的值;2、询问a、b两点路径上边权的最大值。
树链剖分。
#include
#include
#include
#include
using namespace std;
#define maxn 100100
#define lson (pos<<1)
#define rson (pos<<1|1)
//-----------------------------------建边部分-------------------------
int cnt, head[maxn];
struct Edge
{
int to,next;
}e[maxn*3];
void Add_edge(int a, int b)
{
e[cnt].to=b;
e[cnt].next=head[a];
head[a]=cnt++;
}
//-----------------------------------树链部分-------------------------
//记siz[v]表示以v为根的子树的节点数,dep[v]表示v的深度(根深度为1)
//top[v]表示v所在的链的顶端节点,fa[v]表示v的父亲
//son[v]表示与v在同一重链上的v的儿子节点(姑且称为重儿子)
//ti[v]表示v与其父亲节点的连边(姑且称为v的父边)在线段树中的位置
int son[maxn], top[maxn], sz[maxn], dep[maxn], fa[maxn], ti[maxn], dfs_clock;
int n,m;
void dfs_find(int u, int pa, int depth)
{
son[u]=0;sz[u]=1;dep[u]=depth;fa[u]=pa;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v=e[i].to;
if(v==pa)continue;
dfs_find(v,u,depth+1);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]])son[u]=v;
}
}
void dfs_time(int u, int pa)
{
ti[u]=++dfs_clock; top[u]=pa;
if(son[u]!=0)dfs_time(son[u],top[u]);
for(int i = head[u]; i != -1; i = e[i].next)
if(e[i].to!=son[u]&&e[i].to!=fa[u])
dfs_time(e[i].to, e[i].to);
}
//-----------------------------------线段树部分-------------------------
struct node
{
int l,r,val,mx;
int mid(){return (l+r)>>1;}
}tree[maxn<<2];
void build(int pos, int l, int r)
{
tree[pos].l=l;tree[pos].r=r;tree[pos].mx=tree[pos].val=-0x7ffffff;
if(l==r)return ;
int mid=tree[pos].mid();
build(lson,l,mid);
build(rson,mid+1,r);
}
void update(int pos, int id, int w)
{
if(tree[pos].l==tree[pos].r)
{
tree[pos].mx=tree[pos].val=w;
return ;
}
int mid=tree[pos].mid();
if(mid>=id)update(lson,id,w);
else update(rson,id,w);
tree[pos].mx=max(tree[lson].mx,tree[rson].mx);
}
int query(int pos, int L, int R)
{
if(L<=tree[pos].l&&tree[pos].r<=R)
return tree[pos].mx;
int mid=tree[pos].mid();
int ans=-0x7ffffff;
if(mid>=L)ans=max(ans, query(lson,L,R));
if(middep[y])swap(x,y);
if(x!=y)
ans=max(ans,query(1,ti[x]+1,ti[y])); //这里的ti[x]指的是x与其父亲的边,所以一定注意+1
return ans;
}
void ini()
{
cnt=dfs_clock=0;
memset(head,-1,sizeof(head));
}
int da[maxn][3];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ini();
for(int i = 1; i < n; i++)
{
scanf("%d%d%d",&da[i][0],&da[i][1],&da[i][2]);
Add_edge(da[i][0],da[i][1]);
Add_edge(da[i][1],da[i][0]);
}
dfs_find(1,1,1);
dfs_time(1,1);
build(1,2,n);
for(int i = 1; i < n; i++)
{
if(dep[da[i][0]]>dep[da[i][1]])swap(da[i][0],da[i][1]);
update(1,ti[da[i][1]],da[i][2]);
}
char he[100];
while(1)
{
scanf("%s",he);
if(he[0]=='D')break;
if(he[0]=='Q')
{
int a,b;scanf("%d%d",&a,&b);
printf("%d\n",lca(a,b));
}
else
{
int a,b;scanf("%d%d",&a,&b);
update(1,ti[da[a][1]],b);
}
}
printf("\n");
}
return 0;
}