SPOJ 375 Query on a tree
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的更多相关文章
- SPOJ 375. Query on a tree (动态树)
375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...
- SPOJ 375. Query on a tree (树链剖分)
Query on a tree Time Limit: 5000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Ori ...
- spoj 375 Query on a tree(树链剖分,线段树)
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Sub ...
- 动态树(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) ...
- 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 ...
- SPOJ 375 Query on a tree 树链剖分模板
第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...
- spoj 375 query on a tree LCT
这道题是树链剖分的裸题,正在学LCT,用LCT写了,发现LCT代码比树链剖分还短点(但我的LCT跑极限数据用的时间大概是kuangbin大神的树链剖分的1.6倍,所以在spoj上是850ms卡过的). ...
- 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, ...
- SPOJ 375 Query on a tree【树链剖分】
题目大意:给你一棵树,有两个操作1.修改一条边的值,2.询问从x到y路径上边的最大值 思路:如果树退化成一条链的话线段树就很明显了,然后这题就是套了个树连剖分,调了很久终于调出来第一个模板了 #inc ...
- SPOJ 375 Query on a tree(树链剖分)
https://vjudge.net/problem/SPOJ-QTREE 题意: 给出一棵树,树上的每一条边都有权值,现在有查询和更改操作,如果是查询,则要输出u和v之间的最大权值. 思路: 树链剖 ...
随机推荐
- 9月23日JavaScript作业----两个列表之间移动数据
作业一:两个列表之间数据从一个列表移动到另一个列表 <div style="width:600px; height:500px; margin-top:20px"> & ...
- Java 创建文件夹和文件
String path="D://my"; File folder=new File(path); if(!folder.exists() && !folder.i ...
- Java Web的两种开发模式
参考文献:http://www.cnblogs.com/xdp-gacl/p/3908610.html 一.Jsp+JavaBean 此模式如下图所示:
- QT 初阶 第二章 创建对话框(查找对话框实例)
最终效果图: 该对话框由三个文件组成:finddialog.h .finddialog.cpp. main.cpp 代码+注释 /*--finddialog.h--*/ #ifndef FINDDIA ...
- Sencha Touch 2.2 Store Proxy 异常监控
移动端到服务端通信往往会发生很多莫名的异常情况,如何有效的监控proxy异常,给用户友好的用户体验呢? Proxy给我提供了异常exception的监听事件,只需要监控该项目即可. Sencha To ...
- 【转】七年IT经验的七个总结
http://www.unitymanual.com/thread-30000-1-1.html?_dsign=ebe6a043 1.分享第一条经验:“学历代表过去.能力代表现在.学习力代表未来.” ...
- Mac安装Brew
安装命令如下:curl -LsSf http://github.com/mxcl/homebrew/tarball/master | sudo tar xvz -C/usr/local --strip ...
- EditPlus开发Python的简单设置
EditPlus是一个功能强大的编辑器,这里介绍用它来开发Python程序所需要的简单设置. 环境:win7 1.设置Python语法缩进: [1]工具-->设置用户自定义工具 [2]在分类面板 ...
- 不下载SDK启动Android Studio
一.不下载SDK启动Android Studio 给一个解决方法:Android Studio安装目录下的bin,idea.properties:idea.properties文件末尾加一行:disa ...
- centos 7.0 ssh 登陆
CentOS 7.0 最小化安装 默认连接 默认端口是22 安装完查看IP 命令 ip addr ip: 192.168.1.103 自己家里练习的机子 都没改配置了 使用putty 远程连接 下载页 ...