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. 9月8日HTML表单元素(form、文本、按钮、选择)

    表单元素 一.form form代表表单,功能:用于申明表单,定义采集数据的范围,也就是<form>和</form>里面包含的数据将被提交到服务器或者电子邮件里.<for ...

  2. JavaWeb学习笔记——XML和SAX解析区别

  3. 免费api大全

    天气接口 气象局接口 完整数据:http://m.weather.com.cn/data/101010100.html 解析 用例 当天数据:http://www.weather.com.cn/dat ...

  4. Could not load file or assembly Microsoft.Web.Infrastructure

    Error info:Could not load file or assembly 'Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=n ...

  5. 微型orm fluentdata

    http://fluentdata.codeplex.com/documentation#Query

  6. Tomcat服务器原理详解

    [目录]本文主要讲解Tomcat启动和部署webapp时的原理和过程,以及其使用的配置文件的详解.主要有三大部分: 第一部分.Tomcat的简介和启动过程 第二部分.Tomcat部署webapp 第三 ...

  7. centos 7.0 查看根目录下所有文件夹

    centos 7.0最小化安装 第一行是登录 [root@localhost ~]# [root@localhost ~]# cd ../ [root@localhost /]# ls bin dev ...

  8. JS 根据特定URL获取ID数组

    工作中遇到的问题 咱是菜鸟  有更好的方法 求大神看到的指点 事情经过主要是后台返回商品ID 和 商品数量 然后做个卖光的遮罩 这样的效果  结果 后台返回的ID 数组不是后台输入的时候的排序 也就是 ...

  9. input实时监听value change

    oninput ie9+,otheronpropertychange  ie6-8 js使用 var el = docuemnt.getElementById('id'); if('oninput' ...

  10. java正则表达式 --简单认识

    学习目标 正则表达式的作用正则表达式的模式匹配Pattern类和Matcher类的使用掌握String对正则的支持具体内容一.认识正则(为什么要有正则) 方便的对数据进行匹配 执行复杂的字符串验证.拆 ...