Description

给出一个树,每条边有边权,支持两种操作,询问 \(u,v\) 路径上边权最大值,修改第 \(i\) 条边的边权,\(n\leqslant 10^4,T\leqslant 10\)

Sol

树链剖分.

基于边的树链剖分,对于一个点,可能有许多儿子,但是它只能有一个父亲,给它编号表示它到它父亲的边,只需要修改查询的是最后一步就可以了.

Code

#include<cstdio>
#include<vector>
#include<iostream>
using namespace std; #define debug(a) cout<<#a<<"="<<a<<" "
#define mid ((l+r)>>1)
#define lc (o<<1)
#define rc (o<<1|1)
const int N = 10005; inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; } int n,e,cnt;
struct Edge{ int fr,to,v; }edge[N];
vector<Edge> g[N];
int f[N],cost[N],dep[N],son[N],top[N],sz[N],p[N];
int d[N<<2]; void Add_Edge(int fr,int to,int v){
edge[++e]=(Edge){ fr,to,v };
g[fr].push_back((Edge){ fr,to,v });
g[to].push_back((Edge){ to,fr,v });
}
void DFS1(int u,int fa){
sz[u]=1,son[u]=0,dep[u]=dep[fa]+1,f[u]=fa;
for(int i=0,lim=g[u].size(),v;i<lim;i++) if((v=g[u][i].to)!=fa){
DFS1(v,u),sz[u]++;
if(!son[u]||sz[son[u]]<sz[v]) son[u]=v;
}
}
void DFS2(int u,int tp){
p[u]=++cnt,top[u]=tp;
if(son[u]) DFS2(son[u],tp);
for(int i=0,lim=g[u].size(),v;i<lim;i++) if((v=g[u][i].to)!=f[u]&&v!=son[u])
DFS2(v,v);
}
void Build(int o,int l,int r){
if(l==r){ d[o]=cost[l];return; }
Build(lc,l,mid),Build(rc,mid+1,r);
d[o]=max(d[lc],d[rc]);
}
void Change(int o,int l,int r,int x,int v){
if(l==r){ d[o]=v;return; }
if(x<=mid) Change(lc,l,mid,x,v);
else Change(rc,mid+1,r,x,v);
d[o]=max(d[lc],d[rc]);
}
int QueryMax(int o,int l,int r,int L,int R){
if(L<=l&&r<=R) return d[o];int res=0;
if(L<=mid) res=max(res,QueryMax(lc,l,mid,L,R));
if(R>mid) res=max(res,QueryMax(rc,mid+1,r,L,R));
return res;
}
int GetAns(int u,int v){
int res=0,f1=top[u],f2=top[v];
while(f1!=f2){
if(dep[f1]<dep[f2]) swap(u,v),swap(f1,f2);
res=max(res,QueryMax(1,1,n,p[f1],p[u]));
u=f[f1],f1=top[u];
}
if(dep[u]>dep[v]) swap(u,v);
if(dep[v]==dep[u]) return res;
else return max(res,QueryMax(1,1,n,p[u]+1,p[v]));
}
void clr(){ for(int i=0;i<N;i++) g[i].clear();cnt=0,e=0; } int main(){
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
ios::sync_with_stdio(false);
for(int T=in();T--;){
clr();
n=in();
for(int i=1,a,b,c;i<n;i++) a=in(),b=in(),c=in(),Add_Edge(a,b,c);
DFS1(1,1),DFS2(1,1); for(int i=1;i<n;i++){
int a=edge[i].fr,b=edge[i].to;
if(dep[a]>dep[b]) swap(a,b),swap(edge[i].fr,edge[i].to);
cost[p[b]]=edge[i].v;
} Build(1,1,n);
for(char opt[10];;){
scanf("%s",opt);
if(opt[0]=='D') break;
int a=in(),b=in();
if(opt[0]=='C') Change(1,1,n,p[edge[a].to],b);
else printf("%d\n",GetAns(a,b));
// debug(QueryMax(1,1,n,1,1)),debug(QueryMax(1,1,n,2,2)),debug(QueryMax(1,1,n,3,3))<<endl;
}
}return 0;
}

  

SPOJ 375 Query on a tree的更多相关文章

  1. SPOJ 375. Query on a tree (动态树)

    375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...

  2. SPOJ 375. Query on a tree (树链剖分)

    Query on a tree Time Limit: 5000ms Memory Limit: 262144KB   This problem will be judged on SPOJ. Ori ...

  3. spoj 375 Query on a tree(树链剖分,线段树)

      Query on a tree Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Sub ...

  4. 动态树(Link Cut Tree) :SPOJ 375 Query on a tree

    QTREE - Query on a tree #number-theory You are given a tree (an acyclic undirected connected graph) ...

  5. spoj 375 Query on a tree (树链剖分)

    Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges ...

  6. SPOJ 375 Query on a tree 树链剖分模板

    第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...

  7. spoj 375 query on a tree LCT

    这道题是树链剖分的裸题,正在学LCT,用LCT写了,发现LCT代码比树链剖分还短点(但我的LCT跑极限数据用的时间大概是kuangbin大神的树链剖分的1.6倍,所以在spoj上是850ms卡过的). ...

  8. SPOJ 375 Query on a tree(树链剖分)(QTREE)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  9. SPOJ 375 Query on a tree【树链剖分】

    题目大意:给你一棵树,有两个操作1.修改一条边的值,2.询问从x到y路径上边的最大值 思路:如果树退化成一条链的话线段树就很明显了,然后这题就是套了个树连剖分,调了很久终于调出来第一个模板了 #inc ...

  10. SPOJ 375 Query on a tree(树链剖分)

    https://vjudge.net/problem/SPOJ-QTREE 题意: 给出一棵树,树上的每一条边都有权值,现在有查询和更改操作,如果是查询,则要输出u和v之间的最大权值. 思路: 树链剖 ...

随机推荐

  1. Latent Semantic Analysis (LSA) Tutorial 潜语义分析LSA介绍 一

    Latent Semantic Analysis (LSA) Tutorial 译:http://www.puffinwarellc.com/index.php/news-and-articles/a ...

  2. JAVA第三周课后作业

    JAVA课后作业 一.枚举类型 代码: enum Size{SMALL,MEDIUM,LARGE}; public cl ass EnumTest { public static void main( ...

  3. Java Web学习笔记-Servle生命周期

    Servlet会在服务器启动或第一次请求该Servlet的时候开始生命周期,在服务器停止的时候结束生命周期. 无论请求多少次Servlet,最多只有一个Servlet实例.多个客户端并发请求Servl ...

  4. macbook 放flash发烫,转html5

    http://zythum.sinaapp.com/youkuhtml5playerbookmark/

  5. LeetCode —— Merge k Sorted Lists

    /* ** 算法的思路: ** 1.将k个链表的首元素进行建堆 ** 2.从堆中取出最小的元素,放到链表中 ** 3.如果取出元素的有后续的元素,则放入堆中,若没有则转步骤2,直到堆为空 */ #in ...

  6. HighCharts学习笔记(一)HighCharts入门

    一.HighCharts简介 Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表,并且免费提供给个人学习.个人网站 ...

  7. redis入侵小结

    redis安装: windows安装包:http://pan.baidu.com/s/1i3jLlC5 下载下来之后,开始安装: redis-server.exe redis.conf: 简单一步,安 ...

  8. 【转】常用的shell脚本

    from:http://blog.sina.com.cn/s/blog_4152a9f501013r6c.html 常用的shell脚本 (2012-10-10 22:09:07) 转载▼ 标签: 杂 ...

  9. Spring Data JPA 的配置文件 已经数据库的状态

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  10. HTTP协议详解(真的很经典)

    HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展.目前在WWW中使用的是HTTP/1.0 ...