poj 2763(RMQ+BIT\树链剖分)
https://www.cnblogs.com/violet-acmer/p/9686774.html
题意:
一对夫妇居住在xx村庄,小屋之间有双向可达的道路,不会出现环,即所构成的图是个树,从ai小屋到bi小屋需要花费wi时间,一开始,女主角在s小屋,有两个询问,
①0 u : 她又个孩子在u屋,需要妈妈接她回家,输出从s到u所需的最短时间。
②1 x val : 由于种种原因,第x条道路的行走时间由之前的w[x]变为了val。
题解:
(1)RMQ+BIT
因为树中连接两点的路径是唯一的,如果我们对顶点进行合理排列的话,能否像链状时那样,进行类似的处理呢?
考虑利用RMQ计算LCA时所用的,按DFS访问的顺序排列顶点序列。
这样,u和v之间的路径,就是在序列中u 和 v 之间的所有边减去往返重复的部分得到的结果。

于是,只要令边的权重沿叶子方向为正,沿根方向为负,那么往返重复的部分就自然抵消了,于是有
(u,v之间的花费的时间)=(从LCA(u,v)到u的花费的时间和)+(从LCA(u,v)到v的花费的时间和);
同链状情况一样,利用BIT的话,计算权重和更新边权都可以在O(logn)时间内办到,而LCA也能够在O(longn)时间内求得。
(2)树链剖分
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
#define pb push_back
#define mem(a,b) (memset(a,b,sizeof a))
#define lowbit(x) (x&(-x))
;
int n,q,s;
int w[maxn];//存储第 i 条边的权值
struct Node
{
int to;
int w;
int id;
Node(int to,int w,int id):to(to),w(w),id(id){}
};
vector<Node >G[maxn];
void addEdge(int u,int v,int cost,int id)
{
G[u].pb(Node(v,cost,id));
G[v].pb(Node(u,cost,id));
}
*maxn];//欧拉序列
*maxn];//深度序列
int id[maxn];//id[i] : 记录节点 i 在欧拉序列中第一次出现的位置
*maxn];//边的下标,i*2 : 叶子方向 i*2+1 : 根方向
int total;//记录欧拉序列的下标总个数,其实最终的 total = 2*n
//================BIT==================
*maxn];//树状数组
void Add(int x,int val)
{
*maxn)
{
bit[x] += val;
x += lowbit(x);
}
}
int Sum(int x)
{
;
)
{
sum += bit[x];
x -= lowbit(x);
}
return sum;
}
//=====================================
//==================RMQ================
struct RMQ
{
][*maxn];
void Init(){
;i < *maxn;++i)
dp[][i]=i;
}
void ST()
{
);
;i <= k;++i)
;j <= (total-(<<i));++j)
][j]] > depth[dp[i-][j+(<<(i-))]])//dp[i][j] : 记录的是下标
dp[i][j]=dp[i-][j+(<<(i-))];
else
dp[i][j]=dp[i-][j];
}
int Lca(int u,int v)
{
if(u > v)
swap(u,v);
)/log();
<<k)+]])
<<k)+]];
return vs[dp[k][u]];//返回 u,v 的lca
}
}_rmq;
//=====================================
void Dfs(int u,int f,int d)
{
vs[total]=u;
depth[total]=d;
id[u]=total++;
;i < G[u].size();++i)
{
Node &e=G[u][i];
if(e.to != f)
{
Add(total,e.w);//叶子方向,+e.w
es[*e.id]=total;//记录朝向叶子方向的边
Dfs(e.to,u,d+);
vs[total]=u;
depth[total++]=d;
Add(total,-e.w);//根方向, -e.w
es[*e.id+]=total;//记录朝向根方向的边
}
}
}
void Init()
{
_rmq.Init();
total=;
mem(bit,);
;i < maxn;++i)
G[i].clear();
}
int main()
{
while(~scanf("%d%d%d",&n,&q,&s))
{
Init();
;i < n;++i)
{
int u,v;
scanf("%d%d%d",&u,&v,w+i);
addEdge(u,v,w[i],i);
}
Dfs(,-,);
_rmq.ST();
;i <= q;++i)
{
int type;
scanf("%d",&type);
)
{
int u;
scanf("%d",&u);
int lca=_rmq.Lca(id[u],id[s]);
printf(*Sum(id[lca]));
s=u;
}
else
{
int x,val;
scanf("%d%d",&x,&val);
Add(es[x*],val-w[x]);//w[x] 变为 val,需要在原基础上加上 val-w[x]
Add(es[x*+],w[x]-val);//朝向根方向的加负值
w[x]=val;
}
}
}
;
}
RMQ+BIT
poj 2763(RMQ+BIT\树链剖分)的更多相关文章
- POJ - 2763 Housewife Wind (树链剖分/ LCA+RMQ+树状数组)
题意:有一棵树,每条边给定初始权值.一个人从s点出发.支持两种操作:修改一条边的权值:求从当前位置到点u的最短路径. 分析:就是在边可以修改的情况下求树上最短路.如果不带修改的话,用RMQ预处理LCA ...
- POJ 2763 Housewife Wind (树链剖分 有修改单边权)
题目链接:http://poj.org/problem?id=2763 n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置:1操作是第i条 ...
- poj 2763 Housewife Wind : 树链剖分维护边 O(nlogn)建树 O((logn)²)修改与查询
/** problem: http://poj.org/problem?id=2763 **/ #include<stdio.h> #include<stdlib.h> #in ...
- poj 2763 Housewife Wind(树链拆分)
id=2763" target="_blank" style="">题目链接:poj 2763 Housewife Wind 题目大意:给定一棵 ...
- HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- poj 3237 Tree(树链剖分,线段树)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7268 Accepted: 1969 Description ...
- POJ 3237 Tree (树链剖分)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 2825 Accepted: 769 Description ...
- POJ 2243 [SDOI2011]染色 | 树链剖分+线段树
原题链接 肯定是树链剖分的题啦 树剖怎么做可以看我上一篇博客 如果我们已经剖完了: 然后考虑怎么维护重链和查询 用线段树维护的时候当前区间的区间颜色个数应该等于左儿子+右儿子,但是当左儿子的右端点和右 ...
- POJ 2763 Housewife Wind 树链拋分
一.前言 这破题WA了一天,最后重构还是WA,最后通过POJ讨论版得到的数据显示,我看上去是把某个变量写错了..于是,还是低级错误背锅啊....代码能力有待进一步提升2333333 二.题意 某家庭主 ...
随机推荐
- jenkins中配置svn 出现absolute path is not allowed
代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 想用jenkins作自动化部署tomcat. svn代码已经checkout到本地目录了(/ ...
- 理解Vue 2.5的Diff算法
DOM"天生就慢",所以前端各大框架都提供了对DOM操作进行优化的办法,Angular中的是脏值检查,React首先提出了Virtual Dom,Vue2.0也加入了Virtual ...
- STL next_permutation()
用法 字典序全排列 可以发现函数next_permutation()是按照字典序产生排列的,并且是从数组中当前的字典序开始依次增大直至到最大字典序. 代码 #include<iostream&g ...
- BugPhobia启程篇章:需求分析与功能定位
0x01 :引言 If you weeped for the missing sunset, you would miss all the shining stars 我看着大巴缓缓的驶过街角,我躲在 ...
- java计算器项目
简单的java计算器项目 题目:java计算器项目 一. 题目简介: 一个能进行加减乘除四则运算的小程序 Github链接:https://github.com/lizhenbin/test/tr ...
- 利用ss-redir加速服务器上国外服务的访问
https://blog.microdog.me/2016/06/28/Speed-Up-Network-Accessing-To-Overseas-Services-On-Your-Server/
- [转]ubuntu中查找软件的安装位置
原博客地址:http://www.cnblogs.com/zhuyatao/p/4060559.html ubuntu中的软件可通过图形界面的软件中心安装,也可以通过命令行apt-get instal ...
- HashMap, HashTable,HashSet,TreeMap 的时间复杂度
hashSet,hashtable,hashMap 都是基于散列函数, 时间复杂度 O(1) 但是如果太差的话是O(n) TreeSet==>O(log(n))==> 基于树的搜索,只需要 ...
- 关于RabbitMQ Queue Argument的简介
1.Message TTL message在队列queue中可以存活多长时间,以毫秒为单位:发布的消息在queue时间超过了你设定的时间就会被删除掉. channel.queueDeclare(&qu ...
- jQuery 簡介
jQuery:是一個js庫,可以極大地簡化編程,“寫得少做得多”. jquery的作用: 挑選元素.操作屬性.事件函數.動畫和效果.ajax: jQuery庫:google和microsoft都支持, ...