LOJ 6192 城市网络(树上倍增)
LOJ #6192. 「美团 CodeM 复赛」城市网络(链接)
一棵以 $ 1 $ 号节点为根的树,每个点有一个权值,有 $ q $ 个询问,每次从 $ x $ 点开始往某个祖先 $ y $ 走,初始有权值 $ c $ ,如果路径上遇到更大的权值,那么 $ c $ 改为那个权值,问会修改多少次。数据范围: $ n\leq 2\times 10^5 $
$ solution: $
首先因为本题没有修改操作,所以可以离线维护。然后我们发现如果我们在 $ x $ 处节点被修改权值,那么问题从这个节点开始就等效于:从 $ x $ 节点以其本身权值为初始权值向根节点走。然后此题还有另一个突破口:每一个节点,若以当前节点权值为初始权值,它向根节点走第一个会被修改的节点是确定的!这是倍增的标志!!!
结合上面两个性质,我们可以想出一种做法:用倍增数组 $ f[200005][19] $ 维护祖辈里比他大的节点(第一个比他大的,第二个,第四个,八个........)。如果我们初始权值为 $ v $ ,那么我们只要找到第一个比他大的节点(这个也可以用倍增完成),然后我们在这个节点开始用倍增,因为数组里记录都是比当前节点大的节点,所以我们只需将数组里所有深度小于终点的节点数记录下来即可!
至于预处理,首先我们虚拟一个根节点的父亲,权值无限大。然后更新某个节点处置时,找到父辈里第一个比他大的节点,用这个节点更新当前节点即可。具体寻找时:我们要从父亲节点出发,因为数组里记录的是比他大的节点,我们只需要看看那个节点的权值是否大于当前节点,小于等于才跳,最后得到的节点的父亲即为所求!
$ code: $
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define db double
#define rg register int
using namespace std;
int n,q;
int top;
int a[400005]; //节点权值
int dp[400005]; //节点深度
int f[300005][19]; //树上倍增
// f数组存的是祖辈里比他大的节点(第一个比他大的,第二个,第四个,八个........)
struct su{
int to,next;
}b[800005];
int tou[400005]; //链式前向星
inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
if(sign)return -res; else return res;
}
inline int get(int x,int v){ //找到去根节点的路径上第一个比他大的
if(a[x]>v)return x; //x是他父亲
for(rg i=18;i>=0;--i){
if(a[f[x][i]]<=v)x=f[x][i]; //只有都小于等于他才向上跳,倍增套路
}x=f[x][0]; return x; //小于等于才跳,那么下一个就是第一个比他大的
}
inline void dfs(int i,int fa){
dp[i]=dp[fa]+1; //深度
rg x=get(fa,a[i]); f[i][0]=x; //当前节点还没有值,从父亲开始找
for(rg j=0;j<18;++j)
f[i][j+1]=f[f[i][j]][j]; //用第一个比他大的节点更新倍增信息
for(rg j=tou[i];j;j=b[j].next)
if(b[j].to!=fa)dfs(b[j].to,i);
}
inline int ask(int x,int y,int v){
for(rg i=18;i>=0;--i)
if(a[f[x][i]]<=v)x=f[x][i]; //和get函数差不多,找到第一个比他大的
if(a[x]<=v)x=f[x][0]; //有可能初始节点就比v大
if(dp[x]<dp[y])return 0; //说明没有比他大的
rg res=1;
for(rg i=18;i>=0;--i){
if(dp[f[x][i]]>=dp[y])res+=1<<i,x=f[x][i]; //按照深度一点一点逼近
}return res;
}
int main(){
n=qr(); q=qr();
for(rg i=1;i<=n;++i) a[i]=qr();
for(rg i=1;i<n;++i){
rg x=qr(),y=qr();
b[++top].to=y; b[top].next=tou[x]; tou[x]=top; //居然不开c++11
b[++top].to=x; b[top].next=tou[y]; tou[y]=top; // o(一︿一+)o
} a[0]=1e9; dfs(1,0); //根节点的父亲要赋最大!!!
for(rg i=1;i<=q;++i){
rg x=qr(),y=qr(),z=qr();
printf("%d\n",ask(x,y,z));
}
return 0;
}
LOJ 6192 城市网络(树上倍增)的更多相关文章
- LOJ #6192. 「美团 CodeM 复赛」城市网络 (树上倍增)
#6192. 「美团 CodeM 复赛」城市网络 内存限制:64 MiB 时间限制:500 ms 标准输入输出 题目描述 有一个树状的城市网络(即 nnn 个城市由 n−1n-1n−1 条道路连接 ...
- LibreOJ #6192. 「美团 CodeM 复赛」城市网络
#6192. 「美团 CodeM 复赛」城市网络 内存限制:64 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: sqc 提交提交记录统计讨论测试数据 题目描 ...
- (2016北京集训十三)【xsy1532】网络战争 - 最小割树+树上倍增+KD树
题解: 好题!! 这题似乎能上我代码长度记录的前五? 调试时间长度应该也能上前五QAQ 首先题目要求的明显就是最小割,当然在整个森林上求Q次最小割肯定是会GG的,所以我们需要一个能快速求最小割的算法— ...
- 美团 CodeM 复赛」城市网络
美团 CodeM 复赛」城市网络 内存限制:64 MiB时间限制:500 ms标准输入输出 题目描述 有一个树状的城市网络(即 nnn 个城市由 n−1n-1n−1 条道路连接的连通图),首都为 11 ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
- 【bzoj4568】[Scoi2016]幸运数字 树上倍增+高斯消元动态维护线性基
题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游 ...
- luogu1081 开车旅行 树上倍增
题目大意 小A和小B决定利用假期外出旅行,他们将想去的城市从1到N编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市i 的海拔高度为Hi,城市i 和城市j 之间的距离 ...
- 『保卫王国 树上倍增dp』
保卫王国 Description Z 国有n座城市,n - 1条双向道路,每条双向道路连接两座城市,且任意两座城市 都能通过若干条道路相互到达. Z 国的国防部长小 Z 要在城市中驻扎军队.驻扎军队需 ...
- 最近公共祖先算法LCA笔记(树上倍增法)
Update: 2019.7.15更新 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了 ...
随机推荐
- Spring中基于java的配置
Spring中为了减少XML配置,可以声明一个配置类类对bean进行配置,主要用到两个注解@Configuration和@bean 例子: 首先,XML中进行少量的配置来启动java配置: <? ...
- 将项目发布到neuxs私服
需要在 pom.xml中配置 <distributionManagement> <repository> <id>user-release</id> & ...
- 省市区,级联查询,ajaxgird,ajaxfrom
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 微博获取原图时重定向到图片的url
微博获取原图时重定向到图片的url,所以获取的是乱码 jsoup默认是执行重定向的. //根据Url获取页面对应的Document public static Document getDoc1(Str ...
- Git+Jenkins配置
一.新建任务 admin账户登陆jenkins,点击新建按钮-> 选择构建一个自由风格的软件项目,item name 随便输入一个自己认为有意义的名字,点击OK 二.源码管理 源码管理-> ...
- c# 窗口关闭方法
背景:点击datagridview某条信息弹出信息详情窗口,当连续点击时需要关闭之前的详情窗口. 实现方式: 父窗口中 全局创建子窗口(MsgDetailFrm ): MsgDetailFrm de ...
- 移动端自动化==>Windows-Android-Appium环境搭建
第一步 安装JDK,本机如果带有1.7及以上版本且配置好了环境变量,则可忽略此安装步骤. JDK的安装包,百度下载即可.安装完成后配置环境变量. cmd下验证环境变量是否配置成功 第二步 安装Andr ...
- Scratch少儿编程系列:(九)音乐高级技巧
一.程序说明 本程序用来演奏音乐,相对于“Scratch少儿编程系列:(八)演奏简单音乐”而言,本节介绍的方法适用于复杂点的音乐. 二.程序流程图 为了更直观的描述上述过程,采用流程图的方式将猜数字的 ...
- Java基础之 多线程
一.创建多线程程序的第一种方式: 继承(extends) Thread类 Thread类的子类: MyThread //1.创建一个Thread类的子类 public class MyThread e ...
- 【计算机视觉】HDR之tone mapping简介
tone Mapping原是摄影学中的一个术语,因为打印相片所能表现的亮度范围不足以表现现实世界中的亮度域,而如果简单的将真实世界的整个亮度域线性压缩到照片所能表现的亮度域内,则会在明暗两端同时丢失很 ...