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 二.题意 某家庭主 ...
随机推荐
- Centos7.2下OpenVPN 环境完整部署记录
关于OpenVPN的有关介绍及为何使用OpenVPN在此就不做赘述了,下面直接记录Centos7.2系统下部署OpenVPN环境的操作过程: 1) 先将本机的yum换成阿里云的yum源 [root@t ...
- Linux内核分析:期中总结
第一章:计算机是如何工作的 计算机大部分都是用冯诺依曼体系结构,即存储程序计算机. 两个层面: 1.硬件: cpu(IP寄存器:指针,指向内存的某块区域)——总线——内存(代码与数据) 2.程序员: ...
- shell脚本--shift参数左移
参数左移什么意思呢?这个参数指的是在运行脚本时,跟在脚本名后面的参数,前面已经讲过,可以使用$#来获取参数的个数,使用$*来获取所有的参数,而参数左移的含义是这样的:有个指针指向参数列表第一个参数,左 ...
- SyntaxHighlighter行号显示错误问题解决方案
SyntaxHighlighter是根据代码中的换行符分配行号的.但是,如果一行代码或者注释比较长,在页面显示时需要分成多行显示,会出现行号对不上的问题,像这样: 通过设置CSS强制不换行,可以保证行 ...
- [转帖]浅析Servlet执行原理
浅析Servlet执行原理 原贴地址: https://www.cnblogs.com/wangjiming/p/10360327.html 原作者画的图挺好. 自己之前看过iis的一些配置文档 但是 ...
- Docker 执行nginx以及简单进入container
1. docker run -d --name mynginx nginx 运行起来nginx镜像之后 2. docker exec -ti mynginx /bin/bash 能够进入操作界面 发现 ...
- SQLserver 一种简单的GUI方式创建DBlink copy 表数据的方法
1. 在sqlserver 上面使用GUI的方式创建dblink 首先打开查询分析器 在如下的位置处右键 -新建连接服务器 输入需要copy数据的服务器 输入ip地址 然后建立连接 在打开查询分析器进 ...
- 破解xlsm文件的VBA项目密码和xlsx的工作簿保护密码
工具 待破解的xlsm文件.Excel2010.Hex Editor 步骤 1.修改.xlsm后缀为.zip 2.使用压缩软件打开,进入xl目录找到vbaProject.bin文件,解压出来 3.使用 ...
- chart.js & canvas
chart.js & canvas https://www.chartjs.org/samples/latest/ https://www.chartjs.org/samples/latest ...
- codeforces469B
Chat Online CodeForces - 469B 问题描述 你和你的朋友经常在网上聊天.你的朋友作息规律每天只会在p个时间段[ai,bi]在线.你作息混乱,假设你在t时刻起床,那么你会在q个 ...