SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I
给你一棵有边权的树,有两个操作:一个操作是输出l到r点之间的最大的边权,另一个操作是修改某条边的权值。
这题是树链剖分的简单模版题,代码如下:
//修改单边权
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e4 + ;
struct data {
int next , to , cost;
}edge[MAXN << ];
int head[MAXN] , top[MAXN] , id[MAXN] , par[MAXN] , dep[MAXN] , size[MAXN] , son[MAXN];
int cnt , tot , v[MAXN] , u[MAXN] , cost[MAXN]; void init() {
cnt = tot = ;
memset(head , - , sizeof(head));
} inline void add(int u , int v , int cost) {
edge[cnt].next = head[u];
edge[cnt].to = v;
edge[cnt].cost = cost;
head[u] = cnt++;
} void dfs_1(int u , int p , int d) {
dep[u] = d , par[u] = p , size[u] = , son[u] = u;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
dfs_1(v , u , d + );
if(size[son[u]] < size[v])
son[u] = v;
size[u] += size[v];
}
} void dfs_2(int u , int p , int t) {
top[u] = t , id[u] = ++tot;
if(son[u] != u)
dfs_2(son[u] , u , t);
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p || v == son[u])
continue;
dfs_2(v , u , v);
}
} struct segtree {
int l , r , Max;
}T[MAXN << ]; void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r;
if(l == r)
return ;
build(p << , l , mid);
build((p << )| , mid + , r);
} void updata(int p , int pos , int num) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == T[p].r) {
T[p].Max = num;
return ;
}
if(pos <= mid)
updata(p << , pos , num);
else
updata((p << )| , pos , num);
T[p].Max = max(T[p << ].Max , T[(p << )|].Max);
} int query(int p , int l , int r) {
int mid = (T[p].l + T[p].r) >> ;
if(l == T[p].l && T[p].r == r)
return T[p].Max;
if(r <= mid)
return query(p << , l , r);
else if(l > mid)
return query((p << )| , l , r);
else
return max(query(p << , l , mid) , query((p << )| , mid + , r));
} int Find(int l , int r) {
int pl = top[l] , pr = top[r] , Max = ;
while(pl != pr) {
if(dep[pl] > dep[pr]) {
Max = max(Max , query( , id[pl] , id[l]));
l = par[pl];
pl = top[l];
}
else {
Max = max(Max , query( , id[pr] , id[r]));
r = par[pr];
pr = top[r];
}
}
if(r == l)
return Max;
else if(dep[r] > dep[l])
return max(Max , query( , id[son[l]] , id[r]));
else
return max(Max , query( , id[son[r]] , id[l]));
} int main()
{
int t , n , l , r;
scanf("%d" , &t);
while(t--) {
scanf("%d" , &n);
init();
for(int i = ; i < n ; ++i) {
scanf("%d %d %d" , u + i , v + i , cost + i);
add(u[i] , v[i] , cost[i]);
add(v[i] , u[i] , cost[i]);
}
dfs_1( , , );
dfs_2( , , );
build( , , tot);
for(int i = ; i < n ; ++i) {
if(dep[u[i]] > dep[v[i]])
swap(u[i] , v[i]);
updata( , id[v[i]] , cost[i]);
}
char q[];
while(scanf("%s" , q) && q[] != 'D') {
scanf("%d %d" , &l , &r);
if(q[] == 'C') {
updata( , id[v[l]] , r);
}
else {
printf("%d\n" , Find(l , r));
}
}
}
return ;
}
SPOJ 375 (树链剖分 - 边权剖分 - 修改单边权)的更多相关文章
- SPOJ 375 树链剖分
SPOJ太慢了,SPOJ太慢了, 题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权:2.查询u,v之间路径上的最大边权. 分析:树链剖分入门题,看这里: ...
- SPOJ 375 (树链剖分+线段树)
题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...
- SPOJ 375 树链剖分 QTREE - Query on a tree
人生第一道树链剖分的题目,其实树链剖分并不是特别难. 思想就是把树剖成一些轻链和重链,轻链比较少可以直接修改,重链比较长,用线段树去维护. 貌似大家都是从这篇博客上学的. #include <c ...
- spoj 375 树链剖分 模板
QTREE - Query on a tree #tree You are given a tree (an acyclic undirected connected graph) with N no ...
- POJ 2763 (LCA +RMQ+树状数组 || 树链部分) 查询两点距离+修改边权
题意: 知道了一颗有 n 个节点的树和树上每条边的权值,对应两种操作: 0 x 输出 当前节点到 x节点的最短距离,并移动到 x 节点位置 1 x val 把第 x 条边的权值改为 ...
- spoj 375 树链剖分模板
/* 只是一道树链刨分的入门题,作为模板用. */ #include<stdio.h> #include<string.h> #include<iostream> ...
- FZU 2082 过路费 (树链剖分 修改单边权)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082 树链剖分模版题,求和,修改单边权. #include <iostream> #include ...
- POJ 2763 Housewife Wind (树链剖分 有修改单边权)
题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...
- SPOJ QTREE 树链剖分
树链剖分的第一题,易懂,注意这里是边. #include<queue> #include<stack> #include<cmath> #include<cs ...
随机推荐
- 高斯消元 分析 && 模板 (转载)
转载自:http://hi.baidu.com/czyuan_acm/item/dce4e6f8a8c45f13d7ff8cda czyuan 先上模板: /* 用于求整数解得方程组. */ #inc ...
- HDU 1698 Just a Hook (线段树 成段更新 lazy-tag思想)
题目链接 题意: n个挂钩,q次询问,每个挂钩可能的值为1 2 3, 初始值为1,每次询问 把从x到Y区间内的值改变为z.求最后的总的值. 分析:用val记录这一个区间的值,val == -1表示这 ...
- bzoj3672
感觉是noi2014中最有价值的一道题了 我们先考虑链上这个问题怎么做…… 如果没限制,那就是SB的斜率优化 我们可以得到这个式子(f[j]-f[k])/(s[j]-s[k])<p[i] 点横坐 ...
- Xcode5 编译ffmpeg,arm64版本;H264
编译选项:./configure —-cc=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchai ...
- Android Dialog使用举例
在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框,在我们使用Android的过程中,我归纳了一 ...
- Android平台下实现录音及播放录音功能的简介
录音及播放的方法如下: package com.example.audiorecord; import java.io.File; import java.io.IOException; import ...
- .NET Framework个版本说明
.NET Framework .NET版本 1.0 1.1 2.0 3.0 3.5 4.0 4.5 完整版本 1.0.3705.0 1.1.4322.573 2.0.50727.42 3.0.4506 ...
- SQL 2005 日志损坏的恢复方法
SQL 在突然停电或者非正常关机下,可能会出现日期文件错误,导致数据库不正常.恢复数据库方法如下 1.数据库服务停掉 将数据库文件备份 例如数据库名为 DTMS 则将 DTMS.mdf 备份出来. 2 ...
- Java异常的分类
1. 异常机制 异常机制是指当程序出现错误后,程序如何处理.具体来说,异常机制提供了程序退出的安全通道.当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器. 传 ...
- Reading or Writing to Another Processes Memory in C# z
http://www.jarloo.com/reading-and-writing-to-memory/ Declarations [Flags] public enum ProcessAccessF ...