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 numbered 1, 2, 3...N-1.
We will ask you to perfrom some instructions of the following form:
- CHANGE i ti : change the cost of the i-th edge to ti
or - QUERY a b : ask for the maximum edge cost on the path from node a to node b
Input
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
- In the first line there is an integer N (N <= 10000),
- In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),
- The next lines contain instructions "CHANGE i ti" or "QUERY a b",
- The end of each test case is signified by the string "DONE".
There is one blank line between successive tests.
Output
For each "QUERY" operation, write one integer representing its result.
Example
Input:
1 3
1 2 1
2 3 2
QUERY 1 2
CHANGE 1 3
QUERY 1 2
DONE Output:
1
3
第一次接触树链剖分,貌似是用来处理对树的边权的多次询问,然后对边权进行编号,转化为节点之间的询问。具体关于树链剖分的解析见 http://blog.csdn.net/acdreamers/article/details/10591443
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define lson(x) ((x<<1))
#define rson(x) ((x<<1)+1)
using namespace std;
typedef long long ll;
const int N=1e5+;
const int M=N*N+;
int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N]; //top 最近的重链父节点
int num;
vector<int> v[N];
struct tree {
int x,y,val;
void read() {
scanf("%d%d%d",&x,&y,&val);
}
};
tree e[N];
void dfs1(int u, int f, int d) {
dep[u] = d;
siz[u] = ;
son[u] = ;
fa[u] = f;
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == f) continue;
dfs1(ff, u, d + );
siz[u] += siz[ff];
if (siz[son[u]] < siz[ff])
son[u] = ff;
}
}
void dfs2(int u, int tp) {
top[u] = tp;
id[u] = ++num;
if (son[u]) dfs2(son[u], tp);
for (int i = ; i < v[u].size(); i++) {
int ff = v[u][i];
if (ff == fa[u] || ff == son[u]) continue;
dfs2(ff, ff);
}
} struct Tree {
int l,r,val;
};
Tree tree[*N];
void pushup(int x) {
tree[x].val = max(tree[lson(x)].val, tree[rson(x)].val);
} void build(int l,int r,int v) {
tree[v].l=l;
tree[v].r=r;
if(l==r) {
tree[v].val = val[l];
return ;
}
int mid=(l+r)>>;
build(l,mid,v*);
build(mid+,r,v*+);
pushup(v);
}
void update(int o,int v,int val) { //log(n)
if(tree[o].l==tree[o].r) {
tree[o].val = val;
return ;
}
int mid = (tree[o].l+tree[o].r)/;
if(v<=mid)
update(o*,v,val);
else
update(o*+,v,val);
pushup(o);
}
int query(int x,int l, int r) {
if (tree[x].l >= l && tree[x].r <= r) {
return tree[x].val;
}
int mid = (tree[x].l + tree[x].r) / ;
int ans = ;
if (l <= mid) ans = max(ans, query(lson(x),l,r));
if (r > mid) ans = max(ans, query(rson(x),l,r));
return ans;
} int Yougth(int u, int v) {
int tp1 = top[u], tp2 = top[v];
int ans = ;
while (tp1 != tp2) {
if (dep[tp1] < dep[tp2]) {
swap(tp1, tp2);
swap(u, v);
}
ans = max(query(,id[tp1], id[u]), ans);
u = fa[tp1];
tp1 = top[u];
}
if (u == v) return ans;
if (dep[u] > dep[v]) swap(u, v);
ans = max(query(,id[son[u]], id[v]), ans);
return ans;
}
void Clear(int n) {
for(int i=; i<=n; i++)
v[i].clear();
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
int n;
scanf("%d",&n);
for(int i=; i<n; i++) {
e[i].read();
v[e[i].x].push_back(e[i].y);
v[e[i].y].push_back(e[i].x);
}
num = ;
dfs1(,,);
dfs2(,);
for (int i = ; i < n; i++) {
if (dep[e[i].x] < dep[e[i].y]) swap(e[i].x, e[i].y);
val[id[e[i].x]] = e[i].val;
}
build(,num,);
char s[];
while(~scanf("%s",&s) && s[]!='D') {
int x,y;
scanf("%d%d",&x,&y);
if(s[]=='Q')
printf("%d\n",Yougth(x,y));
if (s[] == 'C')
update(,id[e[x].x],y);
}
Clear(n);
}
return ;
}
spoj 375 Query on a tree (树链剖分)的更多相关文章
- SPOJ 375 Query on a tree 树链剖分模板
第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...
- 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(树链剖分+线段树单点更新,区间查询)
传送门: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 --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- 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, ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Description 给定一棵N个节点的树,每个点 ...
随机推荐
- mongodb导入json文件(WINDOWS)
mongodb导入json格式的文件的命令是mongoimport: 在下面的这个例子中,使用mongoimport命令将文件pi.json中的内容导入loacal数据库的pi集合中. 打开CMD,进 ...
- python3.x 安装命令
在root下执行下面的命令即可: sudo apt-get install python3-dev build-essential libssl-dev libffi-dev libxml2 libx ...
- 抽象类和虚方法、base关键字
微软官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/abstract ...
- 在.net2.0中实现Action和Func方法
由于这两个是在.net3.5中新加入的特性,所以我们需要自己写一下. 格式如下: delegate void Action(); delegate void Action<T, T ...
- 201621123034 《Java程序设计》第7周学习总结
作业07-Java GUI编程 1. 本周学习总结 1.1 思维导图:Java图形界面总结 1.2 可选:使用常规方法总结其他上课内容. 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模 ...
- InfluxDB数据备份和恢复方法,支持本地和远程备份
本文属于<InfluxDB系列教程>文章系列,该系列共包括以下 17 部分: InfluxDB学习之InfluxDB的基本概念 InfluxDB学习之InfluxDB的基本操作 Influ ...
- Codeforces 433 Div.2(A、B、C、D)
A. Fraction 暴力遍历1-1000,取组成的真分数比值最大且分子分母gcd为1时更新答案 代码: #include <stdio.h> #include <algorith ...
- [bzoj2038] [2009国家集训队]小Z的袜子
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只 ...
- [poj] 3304 Segments || 判断线段相交
原题 给出n条线段,判断是否有一条直线与所有线段都有交点 若存在这样一条直线,那么一定存在一条至少过两个线段的端点的直线满足条件. 每次枚举两条线段的两个端点,确定一条直线,判断是否与其他线段都有交点 ...
- POJ 2243 [SDOI2011]染色 | 树链剖分+线段树
原题链接 肯定是树链剖分的题啦 树剖怎么做可以看我上一篇博客 如果我们已经剖完了: 然后考虑怎么维护重链和查询 用线段树维护的时候当前区间的区间颜色个数应该等于左儿子+右儿子,但是当左儿子的右端点和右 ...