SPOJ QTREE Query on a Tree【树链剖分模板题】
树链剖分,线段树维护~
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; const int MAXN = ;
struct Edge
{
int to,next;
}edge[MAXN*];
int head[MAXN],tot;
int top[MAXN];//top[v]表示v所在的重链的顶端节点
int fa[MAXN]; //父亲节点
int deep[MAXN];//深度
int num[MAXN];//num[v]表示以v为根的子树的节点数
int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置
int fp[MAXN];//和p数组相反
int son[MAXN];//重儿子
int pos;
void init()
{
tot = ;
memset(head,-,sizeof(head));
pos = ;
memset(son,-,sizeof(son));
}
void addedge(int u,int v)
{
edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
}
void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son
{
deep[u] = d;
fa[u] = pre;
num[u] = ;
for(int i = head[u];i != -; i = edge[i].next)
{
int v = edge[i].to;
if(v != pre)
{
dfs1(v,u,d+);
num[u] += num[v];
if(son[u] == - || num[v] > num[son[u]])
son[u] = v;
}
}
}
void getpos(int u,int sp) //第二遍dfs求出top和p
{
top[u] = sp;
if(son[u] != -)
{
p[u] = pos++;
fp[p[u]] = u;
getpos(son[u],sp);
}
else
{
p[u] = pos++;
fp[p[u]] = u;
return;
}
for(int i = head[u] ; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(v != son[u] && v != fa[u])
getpos(v,v);
}
} //线段树
struct Node
{
int l,r;
int Max;
}segTree[MAXN*];
void build(int i,int l,int r)
{
segTree[i].l = l;
segTree[i].r = r;
segTree[i].Max = ;
if(l == r)return;
int mid = (l+r)/;
build(i<<,l,mid);
build((i<<)|,mid+,r);
}
void push_up(int i)
{
segTree[i].Max = max(segTree[i<<].Max,segTree[(i<<)|].Max);
}
void update(int i,int k,int val) // 更新线段树的第k个值为val
{
if(segTree[i].l == k && segTree[i].r == k)
{
segTree[i].Max = val;
return;
}
int mid = (segTree[i].l + segTree[i].r)/;
if(k <= mid)update(i<<,k,val);
else update((i<<)|,k,val);
push_up(i);
}
int query(int i,int l,int r) //查询线段树中[l,r] 的最大值
{
if(segTree[i].l == l && segTree[i].r == r)
return segTree[i].Max;
int mid = (segTree[i].l + segTree[i].r)/;
if(r <= mid)return query(i<<,l,r);
else if(l > mid)return query((i<<)|,l,r);
else return max(query(i<<,l,mid),query((i<<)|,mid+,r));
}
int find(int u,int v)//查询u->v边的最大值
{
int f1 = top[u], f2 = top[v];
int tmp = ;
while(f1 != f2)
{
if(deep[f1] < deep[f2])
{
swap(f1,f2);
swap(u,v);
}
tmp = max(tmp,query(,p[f1],p[u]));
u = fa[f1]; f1 = top[u];
}
if(u == v)return tmp;
if(deep[u] > deep[v]) swap(u,v);
return max(tmp,query(,p[son[u]],p[v]));
}
int e[MAXN][];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int n;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for(int i = ;i < n-;i++)
{
scanf("%d%d%d",&e[i][],&e[i][],&e[i][]);
addedge(e[i][],e[i][]);
addedge(e[i][],e[i][]);
}
dfs1(,,);
getpos(,);
build(,,pos-);
for(int i = ;i < n-; i++)
{
if(deep[e[i][]] > deep[e[i][]])
swap(e[i][],e[i][]);
update(,p[e[i][]],e[i][]);
}
char op[];
int u,v;
while(scanf("%s",op) == )
{
if(op[] == 'D')break;
scanf("%d%d",&u,&v);
if(op[] == 'Q')
printf("%d\n",find(u,v));
else update(,p[e[u-][]],v);
}
}
return ;
}
SPOJ QTREE Query on a Tree【树链剖分模板题】的更多相关文章
- spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)
传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...
- SPOJ QTREE Query on a tree ——树链剖分 线段树
[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...
- 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 ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- SPOJ 375 Query on a tree 树链剖分模板
第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...
- spoj 375 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- 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 ...
- Query on a tree 树链剖分 [模板]
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
随机推荐
- AcWing 908. 最大不相交区间数量
//1.将每个区间按右端点从小到大排序 //2.从前往后依次枚举每个区间,如果当前区间中已经包含点,就直接跳过,否则,选择当前区间的右端点 //选右端点的话,可以尽可能的包含在多个区间里 //那么选的 ...
- 【转】Git常用命令指南
1.git init 初始化一个Git仓库,git init –bare example.git创建一个裸仓,即没有工作区的git仓库.2.添加文件到Git仓库,分两步:git add <fil ...
- Flink流处理(四)- 时间语义
4. 时间语义(Time Semantics) 这章我们会介绍时间语义,以及在流中,对于时间的各种不同的概念的描述.同时我们也会讨论一个流处理器在事件乱序的情况下,如何能提供精准的结果,以及如何使用流 ...
- Reading Comprehensive
我是红色 When I re-entered the full-time workforce a few years ago after a decade of solitary[隐士,独居] sel ...
- HTML学习(8)超链接
<a href="url">链接文本或图片</a> 可以使用id属性来访问标记的地方,例: <a id="tip">被访问的 ...
- 隐藏wordpress版本信息
在主题中的functions.php中添加如下代码: remove_action( 'wp_head', 'wp_generator');
- 题解 P3951 小凯的疑惑
P3951 小凯的疑惑 数论极菜的小萌新我刚看这题时看不懂exgcd做法的题解,后来在网上找到了一篇博客,感觉代码和推导都更加清新易懂,于是在它的基础上写了题解qwq 分析 两数互质,且有无限个,想到 ...
- vs2017运行网站,代码停止,浏览器页面关闭问题解决
问题描述: 在项目开发过程中,如果程序出现了异常,我们一般都会暴露在浏览器中,但是最近我使用vs2017,发现项目一旦停止,浏览器也自动关闭了,没法查看具体错误详情(当然除了单步调试什么的),很是不爽 ...
- php商城数据库的设计 之无限分类
商品分类,使用无限分类 即: -------如何创建数据表 pid---父级分类id,如果是顶级分类则为0 path---1,用户分类的排序 . 排序示例: 实现逻辑:获取type表的所有分类,ord ...
- [Java] 多线程基础详细总结,附加详细实例
详细代码在文章底部 目录 基础概念 进程与线程 单线程与多线程 实现线程的4中方式 thread.start()和runnable.run()的区别 Thread和Runnable的异同 线程的基本操 ...