SPOJ 375. Query on a tree (树链剖分)
Query on a tree
64-bit integer IO format: %lld Java class name: Main
None
Graph Theory
2-SAT
Articulation/Bridge/Biconnected Component
Cycles/Topological Sorting/Strongly Connected Component
Shortest Path
Bellman Ford
Dijkstra/Floyd Warshall
Euler Trail/Circuit
Heavy-Light Decomposition
Minimum Spanning Tree
Stable Marriage Problem
Trees
Directed Minimum Spanning Tree
Flow/Matching
Graph Matching
Bipartite Matching
Hopcroft–Karp Bipartite Matching
Weighted Bipartite Matching/Hungarian Algorithm
Flow
Max Flow/Min Cut
Min Cost Max Flow
DFS-like
Backtracking with Pruning/Branch and Bound
Basic Recursion
IDA* Search
Parsing/Grammar
Breadth First Search/Depth First Search
Advanced Search Techniques
Binary Search/Bisection
Ternary Search
Geometry
Basic Geometry
Computational Geometry
Convex Hull
Pick's Theorem
Game Theory
Green Hackenbush/Colon Principle/Fusion Principle
Nim
Sprague-Grundy Number
Matrix
Gaussian Elimination
Matrix Exponentiation
Data Structures
Basic Data Structures
Binary Indexed Tree
Binary Search Tree
Hashing
Orthogonal Range Search
Range Minimum Query/Lowest Common Ancestor
Segment Tree/Interval Tree
Trie Tree
Sorting
Disjoint Set
String
Aho Corasick
Knuth-Morris-Pratt
Suffix Array/Suffix Tree
Math
Basic Math
Big Integer Arithmetic
Number Theory
Chinese Remainder Theorem
Extended Euclid
Inclusion/Exclusion
Modular Arithmetic
Combinatorics
Group Theory/Burnside's lemma
Counting
Probability/Expected Value
Others
Tricky
Hardest
Unusual
Brute Force
Implementation
Constructive Algorithms
Two Pointer
Bitmask
Beginner
Discrete Logarithm/Shank's Baby-step Giant-step Algorithm
Greedy
Divide and Conquer
Dynamic Programming
Tag it!
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
#include<iostream>
#include<stdio.h>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn = 1e4+; struct node
{
int l,r,Max;
}f[maxn*]; struct Edge
{
int to,next;
}edge[maxn*]; int e[maxn][];
int p[maxn];
int top[maxn];
int siz[maxn];
int son[maxn];
int deep[maxn];
int father[maxn];
int head[maxn];
int num[maxn];
int cont,pos; void init()
{
cont = ;
pos = ;
memset(head,-,sizeof(head));
memset(son,-,sizeof(son));
}
void add(int n1,int n2)
{
edge[cont].to=n2;// 指向谁
edge[cont].next=head[n1];
head[n1]=cont;
cont++;
} void dfs1(int u,int pre,int d)/**fa deep,num,son**/
{
deep[u]=d;
father[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[u]+num[v];
if(son[u]==- || num[v]>num[son[u]])
son[u]=v;
}
}
} void getops(int u,int sp)
{
top[u]=sp;
if(son[u]!=-)
{
p[u]=++pos;
getops(son[u],sp);
}
else
{
p[u]=++pos;
return;
}
for(int i=head[u];i!=-;i=edge[i].next)
{
int v = edge[i].to;
if(v!=son[u] && v!=father[u])
getops(v,v);
}
}
void build(int l,int r,int n)
{
f[n].l=l;
f[n].r=r;
f[n].Max=;
if(l==r)return;
int mid=(l+r)/;
build(l,mid,n*);
build(mid+,r,n*+);
}
int query(int l,int r,int n)
{
int mid=(f[n].l+f[n].r)/;
int ans1,ans2;
if(f[n].l==l && f[n].r==r) return f[n].Max;
if(mid>=r) return query(l,r,n*);
else if(mid<l) return query(l,r,n*+);
else
{
ans1=query(l,mid,n*);
ans2=query(mid+,r,n*+);
if(ans1<ans2) ans1=ans2;
}
return ans1;
}
void update(int x,int num1,int n)
{
int mid=(f[n].l+f[n].r)/;
if(f[n].l == x && f[n].r == x)
{
f[n].Max=num1;
return;
}
if(mid>=x) update(x,num1,n*);
else update(x,num1,n*+);
f[n].Max = f[n*].Max>f[n*+].Max? f[n*].Max:f[n*+].Max;
}
int find(int u,int v)
{
int f1 = top[u],f2 = top[v];
int MAX=;
while(f1!=f2)
{
if(deep[f1]<deep[f2])
{
swap(f1,f2);
swap(u,v);
}
MAX=max(MAX,query(p[f1],p[u],));
u=father[f1];
f1=top[u];
}
if(u==v)return MAX;
if(deep[u]>deep[v])swap(u,v);
return max(MAX,query(p[son[u]],p[v],));
}
int main()
{
int T,n,l,r,x,num1;
char a[];
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init();
for(int i=;i<n;i++)
{
scanf("%d%d%d",&e[i][],&e[i][],&e[i][]);
add(e[i][],e[i][]);
add(e[i][],e[i][]);
}
dfs1(,,);
getops(,);
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][],);
}
while(scanf("%s",a)>)
{
if(a[]=='D')break;
if(a[]=='Q')
{
scanf("%d%d",&l,&r);
printf("%d\n",find(l,r));
}
else if(a[]=='C')
{
scanf("%d%d",&x,&num1);
update(p[e[x][]],num1,);
}
}
}
return ;
}
SPOJ 375. Query on a tree (树链剖分)的更多相关文章
- 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 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个节点的树,每个点 ...
随机推荐
- Oracle TDE的数据加密示例并用logminer验证加密效果
1.确认数据库版本 2创建密钥钱包 3创建加密列的表并初始值 4演示TDE的数据加密示例 5 logminer验证加密效果
- 【HDU4612】 双连通分量求桥
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 题目大意:给你一个无向图,问你加一条边后最少还剩下多少多少割边. 解题思路:好水的一道模板题.先 ...
- vue 倒计时
简单粗暴 export default { data () { return { timer: 30, //默认倒数30秒 stop : false, //默认是停止的,但界面加载之后会变成false ...
- springmvc源码分析
Spring MVC源码分析--初始化过程 标签: springmvcconstructioniocclass 2012-09-09 21:32 26578人阅读 评论(3) 收藏 举报 版权声明:本 ...
- buddy算法
buddy算法是用来做内存管理的经典算法,目的是为了解决内存的外碎片.避免外碎片的方法有两种: 1,利用分页单元把一组非连续的空闲页框映射到非连续的线性地址区间. 2,开发适当的技术来记录现存的空闲连 ...
- Trie树
一.什么是trie树 1.Trie树 (特例结构树) Trie树,又称单词查找树.字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树结构.典型应用是用于统计和排序大量的字符串( ...
- 【iCore3 双核心板_ uC/OS-III】例程十一:任务消息队列
实验指导书及代码包下载: http://pan.baidu.com/s/1pLQYiE3 iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- 多个git账号的配置
问题描述: 作为开发人员,普遍有多个git账号,例如,公司邮箱对应的公司仓储账号和私人邮箱对应的github账号.在一台电脑上使用两个账号基于ssh协议拉代码,如果不进行额外设置,往往只有一个账号可以 ...
- mysql组合索引顺序参考
问题背景 : 当我们需要创建一个组合索引, 索引的顺序对于效率影响很大, 怎么确定索引的顺序; 解决方法 : 我们应该依据字段的全局基数和选择性, 而不是字段的某个具体的值来确定; 表结构 : dc ...
- ERROR 2006 (HY000) at line xx: MySQL server has gone away 解决方法