SPOJ 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 模板题
2种操作:
1.把第i条边的边权更改为v
2.查询路径u,v中最大的边权 注意:是边权,所以查询时候u,v的lca不能包括进来
因为lca所表示的边权并没有在u,v的路径中 树链剖分+线段树(单点更新,区间查询)
线段树连lazy都不用
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> #define LL long long
#define debug printf("eeeeeeeeeeeeeeeeeeeee")
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 using namespace std; const int maxn=1e4+;
const int inf=0x3f3f3f3f; int dep[maxn];
int son[maxn];
int siz[maxn];
int top[maxn];
int fa[maxn];
int chg[maxn];
int rev[maxn];
int cost[maxn];
int e[maxn][]; struct Edge
{
int to,next;
};
Edge edge[maxn<<];
int head[maxn];
int tot; int ma[maxn<<]; void init()
{
memset(head,-,sizeof head);
tot=;
} void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
} void solve(int ); int main()
{
int test;
scanf("%d",&test);
while(test--){
int n;
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][]);
}
solve(n);
}
return ;
} void dfs0(int u,int pre)
{
fa[u]=pre;
siz[u]=;
dep[u]=dep[pre]+;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==pre)
continue;
dfs0(v,u);
siz[u]+=siz[v];
if(son[u]==- || siz[v]>siz[son[u]])
son[u]=v;
}
} void dfs1(int u,int tp)
{
top[u]=tp;
chg[u]=++tot;
rev[tot]=u;
if(son[u]==-)
return ;
dfs1(son[u],tp);
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==fa[u] || v==son[u])
continue;
dfs1(v,v);
}
} void pushup(int rt)
{
ma[rt]=max(ma[rt<<],ma[rt<<|]);
} void build(int l,int r,int rt)
{
if(l==r){
ma[rt]=cost[rev[l]];
return ;
}
int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
} void update(int p,int add,int l,int r,int rt)
{
if(l==r){
ma[rt]=add;
return ;
}
int m=(l+r)>>;
if(p<=m)
update(p,add,lson);
else
update(p,add,rson);
pushup(rt);
} int query(int L,int R,int l,int r,int rt)
{
if(L<=l && R>=r){
return ma[rt];
}
int m=(l+r)>>;
int ret=-inf;
if(L<=m)
ret=max(ret,query(L,R,lson));
if(R>m)
ret=max(ret,query(L,R,rson));
return ret;
} int query_path(int u,int v)
{
int ret=-inf;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])
swap(u,v);
ret=max(ret,query(chg[top[u]],chg[u],,tot,));
u=fa[top[u]];
}
if(dep[u]<dep[v])
swap(u,v);
ret=max(ret,query(chg[v]+,chg[u],,tot,));
return ret;
} void solve(int n)
{
memset(dep,,sizeof dep);
memset(son,-,sizeof son);
memset(cost,,sizeof cost);
dfs0(,);
tot=;
dfs1(,);
for(int i=;i<n;i++){
if(dep[e[i][]]>dep[e[i][]])
swap(e[i][],e[i][]);
cost[e[i][]]=e[i][];
}
build(,tot,);
char str[];
while(scanf("%s",str)){
if(str[]=='D')
break;
int u,v;
scanf("%d %d",&u,&v);
if(str[]=='Q'){
printf("%d\n",query_path(u,v));
}
else{
update(chg[e[u][]],v,,tot,);
}
}
return ;
}
SPOJ 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 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 QTREE - Query on a tree 树链剖分
题目链接 给一棵树, 每条边有权值, 两种操作, 一种是将一条边的权值改变, 一种是询问u到v路径上最大的边的权值. 树链剖分模板. #include <iostream> #includ ...
- Query on a tree——树链剖分整理
树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...
- SPOJ 375 Query on a tree 树链剖分模板
第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...
- SPOJ QTREE Query on a tree --树链剖分
题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...
- Query on a tree 树链剖分 [模板]
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
随机推荐
- Java——集合框架 工具
/* * Arrays工具类的使用 */ public class ArraysTest { public static void main(String[] args) { // TODO A ...
- 时事新闻之 谷歌 google 发布Tensor Flow 源代码
TensorFlow: TensorFlow is an open source software library for numerical computation using data flow ...
- javascript对时间的校验操作
function check() { var startTime=$("#sTime").val(); var endTime=$("#eTime").val( ...
- MySQLdb
MySQLdb的使用 #mysql> create table `account`( # -> `acctid` int(11) default null comment 'XXXX', ...
- Apache Shiro 手册
(一)Shiro架构介绍 一.什么是Shiro Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录 ...
- cocos2dx 2.x mac proj 开启模板
为一个cocos2dx 2.x游戏配了下mac工程,运行后发现clippingNode没起作用,运行TestCpp中的clippingNode示例是起作用的,对比AppController.mm,发现 ...
- HTML5鼠标hover的时候图片放大的效果展示
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 通过CSS禁用页面模块的复制和粘贴功能
样式代码: -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; -khtml-user-select: ...
- nginx设置不使用缓存 add_header Cache-Control no-cache
nginx设置不使用缓存 server { listen 443; #域名 server_name www.dev.163.com; #字符集 charset utf-8; ssl on; ssl_c ...
- ORALCE 游标简单的实例
--取简单的游标 declare cursor sp is select * from user_tables; myrecord user_tables%ROWTYPE; begin open sp ...