[ SPOJ Qtree1 ] Query on a tree
\(\\\)
Description
给定 \(n\) 个点的树,边按输入顺序编号为\(1,2,...n-1\) 。
现要求按顺序执行以下操作(共 \(m\) 次):
\(CHANGE\ i\ t_i\) 将第 \(i\) 条边权值改为 \(t_i\)
\(QUERY\ a\ b\) 询问从 \(a\) 点到 \(b\) 点路径上的最大边权
有多组测试数据,每组数据以 \(DONE\) 结尾
- \(n,m\le 10^5\)
\(\\\)
Solution
重链剖分,线段树维护。
把边权记录在深度较深的叶节点上,具体编号的处理可以利用邻接表存图的方式。
修改就直接找到对应节点时间戳改了就好。
查询找 \(Lca\) 的时候注意不要算上 \(Lca\) 的答案,因为那里记录的是 \(Lca\) 到其父节点的边权。
Updata 的时候把 dfn 手残写成 pos 调了一天
\(\\\)
Code
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
#define gc getchar
#define Rg register
#define mid ((l+r)>>1)
#define inf 2000000000
using namespace std;
inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
}
int n,m,tot,hd[N],bl[N],val[N];
struct edge{int to,nxt,w;}e[N<<1];
inline void add(int u,int v,int w){
e[++tot].to=v; e[tot].w=w;
e[tot].nxt=hd[u]; hd[u]=tot;
}
int sz[N],f[N],d[N],son[N];
void dfs1(int u,int fa){
sz[u]=1; son[u]=0;
for(Rg int i=hd[u],v;i;i=e[i].nxt)
if((v=e[i].to)!=fa){
d[v]=d[u]+1; dfs1(v,u);
val[v]=e[i].w; bl[(i+1)/2]=v;
sz[u]+=sz[v]; f[v]=u;
if(sz[v]>sz[son[u]]) son[u]=v;
}
}
int cnt,dfn[N],top[N],pos[N];
void dfs2(int u,int fa){
dfn[u]=++cnt;
pos[cnt]=u;
if(!top[u]) top[u]=u;
if(son[u]) top[son[u]]=top[u],dfs2(son[u],u);
for(Rg int i=hd[u],v;i;i=e[i].nxt)
if((v=e[i].to)!=fa&&v!=son[u]) dfs2(v,u);
}
struct segment{
int root,ptr;
inline int newnode(){return ++ptr;}
struct node{int ls,rs,mx;}c[N<<1];
inline void pushup(int rt){
c[rt].mx=max(c[c[rt].ls].mx,c[c[rt].rs].mx);
}
void build(int &rt,int l,int r){
rt=newnode();
if(l==r){
c[rt].mx=val[pos[l]];
return;
}
build(c[rt].ls,l,mid);
build(c[rt].rs,mid+1,r);
pushup(rt);
}
void updata(int rt,int l,int r,int p,int x){
if(l==r){c[rt].mx=x;return;}
if(p<=mid) updata(c[rt].ls,l,mid,p,x);
else updata(c[rt].rs,mid+1,r,p,x);
pushup(rt);
}
int query(int rt,int l,int r,int L,int R){
if(l>R||r<L) return 0;
if(l>=L&&r<=R) return c[rt].mx;
int res=-inf;
if(L<=mid) res=max(res,query(c[rt].ls,l,mid,L,R));
if(R>mid) res=max(res,query(c[rt].rs,mid+1,r,L,R));
return res;
}
}tree;
inline int lca(int u,int v){
if(u==v) return 0;
int res=-inf;
while(top[u]!=top[v]){
if(d[top[u]]>d[top[v]]) u^=v^=u^=v;
res=max(res,tree.query(tree.root,1,n,dfn[top[v]],dfn[v]));
v=f[top[v]];
}
if(d[u]>d[v]) u^=v^=u^=v;
res=max(res,tree.query(tree.root,1,n,dfn[u]+1,dfn[v]));
return res;
}
void work(){
n=rd(); cnt=tot=0;
memset(f,0,sizeof(f));
memset(hd,0,sizeof(hd));
memset(top,0,sizeof(top));
memset(val,0,sizeof(val));
for(Rg int i=1,u,v,w;i<n;++i){
u=rd(); v=rd(); w=rd();
add(u,v,w); add(v,u,w);
}
dfs1(1,0); dfs2(1,0);
tree.build(tree.root,1,n);
char c; int x,y;
while(1){
c=gc(); while(!isalpha(c)) c=gc();
if(c=='D') return;
if(c=='Q'){x=rd();y=rd();printf("%d\n",lca(x,y));}
else{x=rd();y=rd();tree.updata(tree.root,1,n,dfn[bl[x]],y);}
}
}
int main(){
int t=rd();
while(t--) work();
return 0;
}
[ SPOJ Qtree1 ] Query on a tree的更多相关文章
- 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 QTREE Query on a tree 树链剖分+线段树
题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...
- QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树
Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...
- 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 (动态树)
375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...
- SPOJ PT07J - Query on a tree III(划分树)
PT07J - Query on a tree III #tree You are given a node-labeled rooted tree with n nodes. Define the ...
- spoj 913 Query on a tree II (倍增lca)
Query on a tree II You are given a tree (an undirected acyclic connected graph) with N nodes, and ed ...
- 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 ...
随机推荐
- 关于SQL SERVER导出数据的问题!
前面一段时间,为这个导出数据真是煞费苦心,网上找了好多资料都没有找到. 从SQL SERVER 2008开始,我们就可以很方便的导出数据脚本,而无需再借助存储过程,但是SQL Server 2012和 ...
- How to force immediate stop of threads in Jmeter servers如何在jmeter执行完,立即停止jmeter
https://stackoverflow.com/questions/38900315/how-to-force-immediate-stop-of-threads-in-jmeter-server ...
- Spring中JavaConfig特性
从Spring3開始,增加了JavaConfig特性.JavaConfig特性同意开发人员不必在Spring的xml配置文件里定义bean,能够在Java Class中通过凝视配置bean,假设你讨厌 ...
- python实现同服站点地址获取
说明:程序使用http://s.tool.chinaz.com/same此站点查询的结果.使用python简单的实现抓取结果 先随便查询一个结果,抓包分析,如图: 使用python模仿post表单,使 ...
- FFmpeg将多张图片合成视频 子视频合并
FFmpeg将多张图片合成视频 - CSDN博客 https://blog.csdn.net/wangshuainan/article/details/77914508 Slideshow – FFm ...
- 修改数据表的字符集为utf8mb4
修改数据表的字符集为utf8mb4
- [mac]WireShark检測不到网卡怎么办?
wireshark是一个很好用的抓包工具,有windows版本号和mac版本号,在mac下安装wireshark,启动后发现提示"There are no interfaces on whi ...
- Bootstrap Tooltip源码分析
/* ======================================================================== * Bootstrap: tooltip.js ...
- js鼠标事情
js鼠标事情 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=" ...
- hdoj--1254--推箱子(bfs好题)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...