spoj 375 树链剖分 模板
QTREE - 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开始
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=;
int id[MAXN+],fa[MAXN+],max_val[MAXN*+],head[MAXN+],son[MAXN+],top[MAXN+],lev[MAXN+],size[MAXN+];
//id:对应到线段树上的点编号,son:重儿子,top:重链的头,lev:深度,size:子树大小
int tot,cnt,val[MAXN+]; //cnt:线段树节点数
struct Edge
{
int u,v,w,next;
}edge[MAXN*+];
void init()
{
for(int i=;i<=MAXN;i++) fa[i]=top[i]=i;
memset(size,,sizeof(size));
memset(head,-,sizeof(head));
memset(val,,sizeof(val));
tot=cnt=;
}
void add(int x,int y,int z)
{
edge[tot].u=x;edge[tot].v=y;edge[tot].w=z;
edge[tot].next=head[x];
head[x]=tot++;
edge[tot].u=y;edge[tot].v=x;edge[tot].w=z;
edge[tot].next=head[y];
head[y]=tot++;
}
void dfs1(int x,int d)
{
lev[x]=d;
son[x]=;
size[x]=;
for(int i=head[x];i!=-;i=edge[i].next){
int y=edge[i].v;
if(y==fa[x]) continue;
fa[y]=x;
dfs1(y,d+);
size[x]+=size[y];
if(size[son[x]]<size[y]) son[x]=y;
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
id[x]=++cnt;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i!=-;i=edge[i].next){
int y=edge[i].v;
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
void pushup(int rt) { max_val[rt]=max(max_val[rt<<],max_val[rt<<|]); }
void build(int l,int r,int rt)
{
if(l==r) { max_val[rt]=val[l];return; }
int mid=(l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
pushup(rt);
}
void update(int id,int c,int l,int r,int rt)
{
if(l==r){
max_val[rt]=c;
return;
}
int mid=(l+r)>>;
if(id<=mid) update(id,c,l,mid,rt<<);
else update(id,c,mid+,r,rt<<|);
pushup(rt);
}
int query(int ql,int qr,int l,int r,int rt)
{
if(ql<=l&&qr>=r) return max_val[rt];
int mid=(l+r)>>,ans=;
if(ql<=mid) ans=max(ans,query(ql,qr,l,mid,rt<<));
if(qr>mid) ans=max(ans,query(ql,qr,mid+,r,rt<<|));
return ans;
}
int solve(int l,int r)
{
int ltp=top[l],rtp=top[r],ans=;
while(ltp!=rtp){
if(lev[rtp]<lev[ltp]){
swap(ltp,rtp);
swap(l,r);
}
ans=max(ans,query(id[rtp],id[r],,cnt,));
r=fa[rtp];
rtp=top[r];
}
if(lev[r]>lev[l]) swap(r,l);
if(l!=r) ans=max(ans,query(id[son[r]],id[l],,cnt,));
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
int t,n;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=;i<n;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
dfs1(,);
dfs2(,);
for(int i=;i<tot;i+=){
if(lev[edge[i].u]>lev[edge[i].v]) swap(edge[i].u,edge[i].v);
val[id[edge[i].v]]=edge[i].w;
}
build(,cnt,);
char ch[];
while(scanf("%s",ch)&&ch[]!='D'){
int x,y;
scanf("%d%d",&x,&y);
if(ch[]=='C') update(id[edge[x*-].v],y,,cnt,);
else printf("%d\n",solve(x,y));
}
}
return ;
}
spoj 375 树链剖分 模板的更多相关文章
- spoj 375 树链剖分模板
/* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...
- SPOJ 375 树链剖分
SPOJ太慢了,SPOJ太慢了, 题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权:2.查询u,v之间路径上的最大边权. 分析:树链剖分入门题,看这里: ...
- SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I 给你一棵有边权的树,有两个操作:一个操作是输出l到 ...
- SPOJ 375 (树链剖分+线段树)
题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...
- SPOJ 375 树链剖分 QTREE - Query on a tree
人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- 算法复习——树链剖分模板(bzoj1036)
题目: 题目背景 ZJOI2008 DAY1 T4 题目描述 一棵树上有 n 个节点,编号分别为 1 到 n ,每个节点都有一个权值 w .我们将以下面的形式来要求你对这棵树完成一些操作:I.CHAN ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- QTREE 树链剖分---模板 spoj QTREE
<树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...
随机推荐
- Centos7.4简单安装使用gitlab+maven+jenkins实现java代码的持续集成部署
1.工具的简单介绍 gitlab--源代码版本管理控制工具 maven--java代码编译构建工具 jenkins--基于java开发的自动化持续集成部署工具 sonar--代码质量管理工具 2.gi ...
- 深入理解JavaScript函数参数
前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascri ...
- 深度学习之神经网络核心原理与算法-caffe&keras框架图片分类
之前我们在使用cnn做图片分类的时候使用了CIFAR-10数据集 其他框架对于CIFAR-10的图片分类是怎么做的 来与TensorFlow做对比. Caffe Keras 安装 官方安装文档: ht ...
- Java多线程编程之不可变对象模式
在多线程环境中,为了保证共享数据的一致性,往往需要对共享数据的使用进行加锁,但是加锁操作本身就会带来一定的开销,这里可以使用将共享数据使用不可变对象进行封装,从而避免加锁操作. 1. 模 ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 0: ordinal not in range(128)的解决
在用爬虫爬取网络小说的时候出现该问题. 估计是字符格式转换格式的错误. 暂时无法解决,搜索了其他博主的解决方案. 以下两个方案靠谱: <一>适用于全篇 import sys default ...
- [buaa-SE-2017]个人作业-week3
个人作业-week3:案例分析 分析产品:Bing词典 Part1:调研&评测 1.软件评测和Bug汇报 这次我选择Bing词典的原因是在于,首先我使用过的词典软件较多,平台涵盖PC端.网站. ...
- vs2013+python+ cocos2d-x-3.3rc0环境搭建
1.vs2013安装一路next,安装即可,时间1~2个小时 2.解压cocos2d-x-3.3rc0 build文件夹里会有名为 cocos2d-win32.vc2012的sln文件 打开 ...
- HTML常用标签及约束
注释 <!--这是一段注释--> 样式表 外部样式(CSS) <head> <link rel="stylesheet" type="tex ...
- HDU 2061 Treasure the new start, freshmen!
http://acm.hdu.edu.cn/showproblem.php?pid=2061 Problem Description background:A new semester comes , ...
- linux ls文件颜色和底色设置
转帖 :linux ls文件颜色和底色设置 白色:表示普通文件蓝色:表示目录绿色:表示可执行文件红色:表示压缩文件浅蓝色:链接文件红色闪烁:表示链接的文件有问题黄色:表示设备文件灰色:表示其他文件 这 ...