题意:链接

定义pos[i]表示i这个值在数组里的下标.

我们先用单调栈找到每个元素左边和右边第一个比它大的元素$l_i$和$r_i$,然后建一棵二叉树,我们就叫做maxtree吧 (upd:mdzz 这就是笛卡尔树)

每个点$i$的父亲是$pos[max(l_i,r_i)]$,如果是$r_i$比较大,那么$i$就是左儿子,$l_i$比较大同理。

当$i$是左儿子时,容易证出$pos[l_i]$在树上的位置就是$i$不停向上走时第一次向左上走遇到的点,反之亦然,设$gfa[x]$表示$x$连向的点中非$fa[x]$的点。

对于每个询问,我们先求出$x,y$的$lca t$,如果$t$不为$x$和$y$,那么最短路上要么经过$t$,要么经过$fa[t]$,这个也很好证(大概就是如果$t$是左儿子,那么$t$的左子树中的点不可能向$fa[t]$上边连边,右边同理)。

定义函数$dis(x,y)$表示$x$到$y$的最短路,其中$y$是$x$的祖先。

当$dep[g[fa[x]]]>=dep[y]$时,显然走$gfa$比较优,然后再在最后一步的时候两种方案取个$min$就行了,问题解决。

#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n,m;
int a[N];
int st[N],ll[N],rr[N],top;
int ch[N][2];
int fa[N][22],fs[N][22],dep[N];
void dfs(int x,int pr,int op)
{
if(ch[x][0])
{
fs[ch[x][0]][0]=x;
dep[ch[x][0]]=dep[x]+1;
if(op==0)
{
fa[ch[x][0]][0]=pr;
dfs(ch[x][0],pr,op);
}
else dfs(ch[x][0],x,op);
}
if(ch[x][1])
{
fs[ch[x][1]][0]=x;
dep[ch[x][1]]=dep[x]+1;
if(op==1)
{
fa[ch[x][1]][0]=pr;
dfs(ch[x][1],pr,op);
}
else dfs(ch[x][1],x,op);
}
return ;
}
void yu()
{
for(int i=1;i<=17;i++)
{
for(int j=1;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-1]][i-1];
fs[j][i]=fs[fs[j][i-1]][i-1];
}
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=17;i>=0;i--)if(dep[fs[x][i]]>=dep[y])x=fs[x][i];
if(x==y)return x;
for(int i=17;i>=0;i--)
{
if(fs[x][i]!=fs[y][i])
{
x=fs[x][i];y=fs[y][i];
}
}
return fs[x][0];
}
int dis(int x,int y)
{
int ans=0;
for(int i=17;i>=0;i--)
{
if(dep[fa[x][i]]>=dep[y])
{
ans+=(1<<i);
x=fa[x][i];
}
}
if(!fa[x][0])return ans+dep[x]-dep[y];
return ans+min(dep[x]-dep[y],2);
}
int solve(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
int t=lca(x,y);
if(t==y)return dis(x,y);
int tmp=dis(x,t)+dis(y,t);
if(t!=1)tmp=min(tmp,dis(x,fs[t][0])+dis(y,fs[t][0]));
return tmp;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
while(top&&a[st[top]]<a[i])top--;
if(top)ll[i]=st[top];
st[++top]=i;
}
top=0;
for(int i=n;i>=1;i--)
{
while(top&&a[st[top]]<a[i])top--;
if(top)rr[i]=st[top];
st[++top]=i;
}
ch[1][1]=n;
for(int i=2;i<=n-1;i++)
{
if(a[ll[i]]<a[rr[i]])ch[ll[i]][1]=i;
else ch[rr[i]][0]=i;
}
dep[1]=1;dfs(1,0,0);dfs(1,0,1);
yu();
int t1,t2;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&t1,&t2);
printf("%d\n",solve(t1,t2));
}
return 0;
}

  

ioi2018集训队自选题:最短路练习题的更多相关文章

  1. 简单数据结构题(from 钟子谦——IOI2018集训队自选题)

    简单数据结构题(from 钟子谦--IOI2018集训队自选题) 试题描述 给一棵 \(n\) 个点的树,点权开始为 \(0\) ,有 \(q\) 次操作,每次操作是选择一个点,把周围一圈点点权 \( ...

  2. 【BZOJ2622】[2012国家集训队测试]深入虎穴 次短路

    [BZOJ2622][2012国家集训队测试]深入虎穴 Description 虎是中国传统文化中一个独特的意象.我们既会把老虎的形象用到喜庆的节日装饰画上,也可能把它视作一种邪恶的可怕的动物,例如“ ...

  3. 【UOJ347】【WC2018】通道 边分治 虚树 DP

    题目大意 给你三棵树,点数都是\(n\).求 \[ \max_{i,j}d_1(i,j)+d_2(i,j)+d_3(i,j) \] 其中\(d_k(i,j)\)是在第\(k\)棵数中\(i,j\)两点 ...

  4. 8月清北学堂培训 Day5

    今天是杨思祺老师的讲授~ 最短路练习题: POJ 1125 Stockbroker Grapevine 有 N 个股票经济人可以互相传递消息,他们之间存在一些单向的通信路径.现在有一个消息要由某个人开 ...

  5. 【6.24校内test】T3 棠梨煎雪

    [题目背景] 岁岁花藻檐下共将棠梨煎雪. 自总角至你我某日辗转天边. 天淡天青,宿雨沾襟. 一年一会信笺却只见寥寥数言. ——银临<棠梨煎雪> [问题描述] 扶苏正在听<棠梨煎雪&g ...

  6. 【LGR-065】洛谷11月月赛 III Div.2

    临近$CSP$...... 下午打了一发月赛,感觉很爽. 非常菜的我只做了前两题......然而听说前两题人均过...... 写法不优秀被卡到$#1067$...... T1:基础字符串练习题: 前缀 ...

  7. BZOJ_2622_[2012国家集训队测试]深入虎穴_最短路

    BZOJ_2622_[2012国家集训队测试]深入虎穴_最短路 Description 虎是中国传统文化中一个独特的意象.我们既会把老虎的形象用到喜庆的节日装饰画上,也可能把它视作一种邪恶的可怕的动物 ...

  8. [转] ACM中国国家集训队论文集目录(1999-2009)

    国家集训队1999论文集 陈宏:<数据结构的选择与算法效率——从IOI98试题PICTURE谈起>来煜坤:<把握本质,灵活运用——动态规划的深入探讨>齐鑫:<搜索方法中的 ...

  9. ACM/ICPC 之 两道dijkstra练习题(ZOJ1053(POJ1122)-ZOJ1053)

    两道较为典型的单源最短路径问题,采用dijkstra解法 本来是四道练习题,后来发现后面两道用dijkstra来解的话总觉得有点冗余了,因此暂且分成三篇博客(本篇以及后两篇). ZOJ1053(POJ ...

随机推荐

  1. Windows环境下实现Consul服务注册和服务发现

    1.首先从官方网站下载Consul,因为我们是使用的Windows系统,所以选择windows版本 https://www.consul.io/downloads.html 2.可以用开发者模式来启动 ...

  2. CAD2020下载安装AutoCAD2020中文版下载地址+安装教程

    AutoCAD2020中文版为目前最新软件版本,我第一时间拿到软件进行安装测试,确保软件正常安装且各项功能正常可以使用,立刻拿出来分享,想用最新版本的话,抓紧下载使用吧: 我把我用的安装包贡献给你下载 ...

  3. JackSon学习笔记(一)

    概述 Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的Java Json解析器”. Jackson框架包含了3个核心库:streaming,databind,annotation ...

  4. python-批量添加图片水印

    前言: 最近总是被无良公众号和培训机构拷贝文章,他们根本不会给你备注原文出处,这种行为真的让人不高兴,所以计划以后的文章都添加上自己的水印. 话不多说,直接上代码. 一.单张图片添加文字水印 # -* ...

  5. Websocket(一)——原理及基本属性和方法

    初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处? 答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起. 举例 ...

  6. Linux内核及分析 第五周 扒开系统调用的三层皮(下)

    实验内容: 1.执行rm menu -rf命令,强制删除原有的menu 2.使用git命令 git clone https://github.com/mengning/menu.git 克隆新的men ...

  7. 《Linux内核分析》第六周笔记 进程的描述和进程的创建

    进程的描述和进程的创建 一.进程的描述 1.进程描述符task_struct数据结构(一) 操作系统的三大功能:进程管理(核心).内存管理.文件系统. 进程控制块PCB——task_struct(进程 ...

  8. 无限级结构SQL查询所有的下级和所有的下级

    Id,PId无限级结构,查询某个Id的所有下级或所有上级,使用WITH AS查询 查找Id为1所有的下级 /*查找Id为1所有的下级*/ WITH T AS( SELECT Id,PId,Name,0 ...

  9. [转载]Memory Limits for Windows and Windows Server Releases

    Memory Limits for Windows and Windows Server Releases This topic describes the memory limits for sup ...

  10. 使用 SSH 秘钥远程连接

    团队开发中常用到 Git.SVN 等版本控制工具,可以大大提高开发效率. 就是将代码统一放到一个代码仓库中,方便管理. 为了安全起见,每次push.pull 代码的时候,都需要输入用户名.密码, 对于 ...