【SPOJ Query on a tree 】 (树链剖分)
http://acm.hust.edu.cn/vjudge/problem/13013
题意:
有一棵N个节点的树(1<=N<=10000),N-1条边,边的编号为1~N-1,每条边有一个权值,要求模拟两种操作:
1:QUERY x y 求节点x和节点y之间的路径中权值最大的边。
2:CHANGE p k修改第p条边的权值为k。
【分析】
树链剖分裸题。。
【表示我一开始怎么TLE,后来怎么AC的并不知道。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
#define Maxn 10010
#define INF 0x7fffffff int mymax(int x,int y) {return x>y?x:y;} struct node
{
int x,y,c,next;
}t[*Maxn];int len; int first[Maxn];
void ins(int x,int y,int c)
{
t[++len].x=x;t[len].y=y;t[len].c=c;
t[len].next=first[x];first[x]=len;
} char s[]; int son[Maxn],dfn[Maxn],top[Maxn],cnt;
int sm[Maxn],fa[Maxn],id[Maxn],dep[Maxn];
void dfs1(int x,int f)
{
dep[x]=dep[f]+;
sm[x]=;son[x]=;fa[x]=f;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
int y=t[i].y;
dfs1(y,x);
sm[x]+=sm[y];
if(son[x]==||sm[son[x]]<sm[y]) son[x]=y;
}
} void dfs2(int x,int tp)
{
dfn[x]=++cnt;top[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x])
dfs2(t[i].y,t[i].y);
} struct nnode
{
int l,r,lc,rc,mx;
}tr[*Maxn];int tot; int build(int l,int r)
{
int x=++tot;
tr[x].l=l;tr[x].r=r;
int mid=(l+r)>>;
if(l!=r)
{
tr[x].lc=build(l,mid);
tr[x].rc=build(mid+,r);
}
tr[x].mx=-INF;
return x;
} void change(int x,int y,int z)
{
if(tr[x].l==tr[x].r)
{
tr[x].mx=z;
return;
}
int mid=(tr[x].l+tr[x].r)>>;
if(y<=mid) change(tr[x].lc,y,z);
else change(tr[x].rc,y,z);
tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx);
} int query(int x,int l,int r)
{
if(tr[x].l==l&&tr[x].r==r) return tr[x].mx;
int mid=(tr[x].l+tr[x].r)>>;
if(r<=mid) return query(tr[x].lc,l,r);
else if(l>mid) return query(tr[x].rc,l,r);
return mymax(query(tr[x].lc,l,mid),query(tr[x].rc,mid+,r));
} int get_ans(int x,int y)
{
int mx=;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
mx=mymax(mx,query(,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(x==y) return mx;
if(dep[x]>dep[y]) swap(x,y);
mx=mymax(mx,query(,dfn[x]+,dfn[y]));
return mx;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
len=;
memset(first,,sizeof(first));
for(int i=;i<n;i++)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
ins(x,y,c);ins(y,x,c);
}
dep[]=;dfs1(,);
cnt=;dfs2(,);
tot=;build(,n);
for(int i=;i<=len;i+=)
{
if(fa[t[i].x]==t[i].y) id[(i+)/]=t[i].x;
else id[(i+)/]=t[i].y;
change(,dfn[id[(i+)/]],t[i].c);
}
while()
{
scanf("%s",s);
if(s[]=='D') break;
int x,y;
scanf("%d%d",&x,&y);
if(s[]=='C')
{
change(,dfn[id[x]],y);
}
else
{
printf("%d\n",get_ans(x,y));
}
}
}
return ;
}
2017-01-21 11:45:00
【SPOJ Query on a tree 】 (树链剖分)的更多相关文章
- SPOJ Query on a tree 树链剖分 水题
You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...
- 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 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 QTREE Query on a tree ——树链剖分 线段树
[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...
- 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, ...
随机推荐
- 【BZOJ】1724 [Usaco2006 Nov]Fence Repair 切割木板
[算法]贪心+堆 #include<cstdio> #include<algorithm> using namespace std; ; int n,heap[maxn],sz ...
- HDU 1728 逃离迷宫 (广搜)
题目链接 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可 ...
- lnmp、lamp、lnmpa一键安装包(Updated: 2016-4-12)
lnmp.lamp.lnmpa一键安装包(Updated: 2016-4-12) 文章目录 脚本特性 安装步骤 如何添加虚拟主机? 如何删除虚拟主机? 如何管理ftp账号? 数据备份 如何管理服务 ...
- 使用ubuntun16.04代码笔记
(1)cd /代表到根目录下面:ls表示将盘中内容列出:cd /home表是打开根目录下的home文件夹:(注意:凡是根目录下的文件夹前面都要加 /) (2)快捷键方式:可以用tab自动补全 (1 ...
- shell 文件内容替换 sed用法
sed 's/要被替换的字符串/新的字符串/g' sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest. 如果没有g标记,则只有每行第一个匹配的 ...
- 2018DDCTF Misc部分WP
题目给出了这样一串字符:d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9e1e6b3e3b9e4b3b7b7 ...
- bootstrap-select属性
# 参考:https://blog.csdn.net/zxl_langya/article/details/79247307 # bootstrap-select属性: <select mult ...
- exit() _exit() 函数区别
exit(): --stdlib.h (1) 所有使用atexit()注册的函数,将会被以注册相反的顺序调用: (2) 所有打开的输出流被刷新,并且关闭流: (3) 使用tmpfile()创建的文件将 ...
- Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)【转】
转自:http://www.linuxidc.com/Linux/2013-06/85221p3.htm 阅读Linux内核源码或对代码做性能优化时,经常会有在C语言中嵌入一段汇编代码的需求,这种嵌入 ...
- visual studio 个性化设置
尼马visual studio 的注释建设的真垃圾 Ctrl+K+C Ctrl+K+U, 通过工具->选项->环境->键盘->命令包含中搜索“注释选定内容”,分配成 Ctrl+ ...