【SPOJ】375. Query on a tree(树链剖分)
http://www.spoj.com/problems/QTREE/
这是按边分类的。
调试调到吐,对拍都查不出来,后来改了下造数据的,拍出来了。囧啊啊啊啊啊啊
时间都花在调试上了,打hld只用了半小时啊囧。
第一次打边分类真没注意一个地方。
就是当fx==fy后,没有判断x==y,然后这是边分类,获得的是父亲的下标,果断错。。
囧,一定要记住这个错误。
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
#define lc x<<1
#define rc x<<1|1
#define lson l, m, lc
#define rson m+1, r, rc
#define MID (l+r)>>1
#define read(x) x=getint()
#define dbg(x) cout << #x << "=" << x << endl
inline const int max(const int& a, const int& b) { return a>b?a:b; }
inline int getint() { char c; int ret=0, k=1; for(c=getchar(); c<'0' || c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0' && c<='9'; c=getchar()) ret=ret*10+c-'0'; return k*ret; } const int N=50010, oo=~0u>>1;
struct Ed { int u, v, w; }e[N];
int ihead[N], inext[N<<1], to[N<<1], cnt;
int fa[N], sz[N], son[N], top[N], dep[N], id[N], mx[N*5], num[N], tot, L, R, key, n; inline void pushup(const int &x) { mx[x]=max(mx[lc], mx[rc]); }
void build(const int &l, const int &r, const int &x) {
if(l==r) { mx[x]=num[l]; return; }
int m=MID;
build(lson); build(rson);
pushup(x);
}
void update(const int &l, const int &r, const int &x) {
if(l==r) { mx[x]=key; return; }
int m=MID;
if(L<=m) update(lson); if(m<R) update(rson); pushup(x);
}
int getmax(const int &l, const int &r, const int &x) {
if(L<=l && r<=R) return mx[x];
int m=MID, ret=oo+1;
if(L<=m) ret=max(ret, getmax(lson)); if(m<R) ret=max(ret, getmax(rson)); return ret;
}
void dfs1(const int &u) {
sz[u]=1; int v;
for(int i=ihead[u]; i; i=inext[i]) if(fa[u]!=(v=to[i])) {
fa[v]=u; dep[v]=dep[u]+1;
dfs1(v);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(const int &u, const int &tp) {
id[u]=++tot; top[u]=tp;
if(son[u]) dfs2(son[u], tp);
for(int i=ihead[u]; i; i=inext[i]) if(fa[u]!=to[i] && to[i]!=son[u]) dfs2(to[i], to[i]);
}
inline int getmax(int x, int y) {
int fx=top[x], fy=top[y], ret=oo+1;
while(fx!=fy) {
if(dep[fx]<dep[fy]) { swap(x, y); swap(fx, fy); }
L=id[fx]; R=id[x];
ret=max(ret, getmax(2, n, 1));
x=fa[fx]; fx=top[x];
}
if(dep[x]>dep[y]) swap(x, y);
if(x!=y) L=id[x]+1; R=id[y]; //这里,如果不特判的话,L会>R,然后线段树那里果断死循环
return max(ret, getmax(2, n, 1));
}
inline void add(const int &u, const int &v) {
inext[++cnt]=ihead[u]; ihead[u]=cnt; to[cnt]=v;
inext[++cnt]=ihead[v]; ihead[v]=cnt; to[cnt]=u;
}
int main() {
int c=getint(), a, b; char ch;
while(c--) {
read(n);
tot=cnt=0;
memset(ihead, 0, sizeof(int)*(n+10));
memset(fa, 0, sizeof(int)*(n+10));
memset(son, 0, sizeof(int)*(n+10));
for(int i=1; i<n; ++i) {
read(e[i].u); read(e[i].v); read(e[i].w);
add(e[i].u, e[i].v);
}
dfs1(1); dfs2(1, 1);
for(int i=1; i<n; ++i) {
if(dep[e[i].u]>dep[e[i].v]) swap(e[i].u, e[i].v);
num[id[e[i].v]]=e[i].w;
}
build(2, n, 1);
for(ch=getchar(); ch<'A' || ch>'Z'; ch=getchar());
while(ch!='D') {
read(a); read(b);
if(ch=='C') { key=b; L=R=id[e[a].v]; update(2, n, 1); }
else printf("%d\n", getmax(a, b));
for(ch=getchar(); ch<'A' || ch>'Z'; ch=getchar());
}
}
return 0;
}
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
【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个节点的树,每个点 ...
随机推荐
- HDU 1285 拓普排序 基本模板例题 确定比赛名次
确定比赛名次 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- [ruby on rails] 跟我学之(1)环境搭建
环境: ubuntu 12.04 (64bit) 代理: 自己最好弄一个代理. 环境配置指令如下: sudo apt-get update sudo apt-get install curl \cur ...
- ubuntu12 apache2部署多个网站的方法
由于对apache2的配置不是很精通.吃了不少瘪. 这里总结下,希望对碰到同样问题的人带来帮助: 假设需求是有两个站点,site1和site2.其端口分别为80和8080. 1. 配置监听端口 修改 ...
- Mac 下 Chrome 浏览器 快捷键
⌘-Option-I 打开“开发人员工具”. ⌘-Option-J 打开“JavaScript 控制台”. ⌘-Option-U 打开当前网页的源代码. 转自: http://www.harbin-s ...
- linux中pip安装步骤与使用详解
pip类似RedHat里面的yum,安装软件非常方便.本节详细介绍pip的安装.以及使用方法,希望文章对各位了解pip的安装与使用带来帮助. 1.pip下载安装1.1 pip下载 代码如下 复制代码 ...
- 19.python笔记之Rabbitmq
RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(MQ)是一种应用程序 ...
- 5.django笔记之form保存表单信息,动态select
作者:刘耀 一.使用form保存用户输入过的信息 场景:例如 如果用户注册,那么他输入n多个表单之后,那么他提交是时候,如果错误返回的时候,那么需要重新再输入表单内容.这样会影响用户体验,所以,使用f ...
- [Android UI] shape和selector的结合使用
shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和 ...
- 第一章 用记事本搭建C#程序
1.新建记事本:using System;class Text{ Console.WriteLine("你好如鹏网"); Console.WriteLine("www.r ...
- 用例视图 Use Case View(rose)
找开Rose工具,选择用例视图 Use Case View 先看看这个视图下面都有哪些工具,都能做一些什么: 下面详细说一下: 用例视图下面有工具: 一:选择工具 二:文本框Text Box 三:注 ...