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, ...
随机推荐
- window7资源管理器一直重启(百度知道找到可用)
今天我的机器也出现这种问题:我的解决方式是,在开机时选择系统修复选项中的进入命令行方式(尝试过用安全模式,文件被占用,现象一样),然后cd C:\Users\Administrator\AppData ...
- php文件遍历类:FileBianli.class.php
<?php class FileBianli{ private $dirname; private $dirsize=0; private $totalsize=0;//当前目录大小 funct ...
- GPU的革命
CUDA 线程执行模型分析(一)招兵------ GPU的革命 CUDA 线程执行模型分析(二)大军未动粮草先行------GPU的革命 CUDA硬件实现分析(一)------安营扎寨-----GPU ...
- 将HTML段赋值给PHP变量的便捷方法,不使用转义字符
<?php $b='12'; $a=<<<sss <html> <head> </head> <body> <i>& ...
- Linux-Nginx之sendfile与上下文切换
今天在看nginx thread pool的时候,频繁的看到sendfile,其实以前也经常看到sendfile,只是我平时选择性的忽视而已... 先说下sendfile,明天在好好聊下nginx 线 ...
- System.Web.HttpContext.Current 跟踪分析
public static HttpContext Current { get { return ContextBase.Current as HttpContext; } set { Context ...
- document cookie用法
cookie概述 曾经利用一个不变的框架来存储购物栏数据,而商品显示页面是不断变化的,尽管这样能达到一个模拟 全局变量的功能,但并不严谨.例如在导航框架页面内右击,单击快捷菜单中的[刷新]命令,则所有 ...
- Eclipse 常用快捷键的使用
Eclipse中10个最有用的快捷键组合 一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合.通过这些组合可以更加容易的浏览源代码,使得整体的开发效率和质量得到提升. ...
- nova分析(7)—— nova-scheduler
Nova-Scheduler主要完成虚拟机实例的调度分配任务,创建虚拟机时,虚拟机该调度到哪台物理机上,迁移时若没有指定主机,也需要经过scheduler.资源调度是云平台中的一个很关键问题,如何做到 ...
- js禁止从浏览器缓存读取消息
$.ajaxSetup ({ cache: false //设置成false将不会从浏览器缓存读取信息 });