题意:链接

定义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. Flutter - 退出App

    Flutter退出App的方法一般有两种 ①SystemNavigator.pop 推荐 onTap: () async { await pop(); }, static Future<void ...

  2. 6大爱上react 的理由

    本文翻译自:https://blog.syncano.io/reactjs-reasons-why-part-1/ 书写javascript 更加简单 (⚠️js 中混用html 也一直是外界所诟病的 ...

  3. Rop框架学习笔记

    1.  提供了开发服务平台的解决方案:比如应用认证.会话管理.安全控制.错误模型.版本管理.超时限制 2.  启动:RopServlet截获http请求 配置: <servlet> < ...

  4. 《Linux内核分析》第四周学习总结

    <Linux内核分析>第四周学习总结                         ——扒开系统调用的三层皮 姓名:王玮怡  学号:20135116 理论总结部分: 第一节 用户态.内核 ...

  5. Linux内核分析第一次学习报告

    Linux内核分析第一次学习报告 学生 黎静 学习内容 1.存储程序计算机工作模型 冯诺依曼体系结构:核心思想为存储程序计算机. CPU抽象为for循环,总是执行下一条指令,内存保存指令和数据,CPU ...

  6. 爬虫时http错误提示

    在爬虫,请求网站的时候,有时候出现域名报错,所出现的代码所对应的意思:

  7. eclipse插件wordwrap

    一行代码很长,浏览不方便,安装wordwrap可以自动折行. help->install new software-,在Workwith输入wordwrap - http://ahtik.com ...

  8. Java微信二次开发(八)

    高级接口,先做了两个(获取用户信息和获取关注者列表) 第一步:找到包com.wtz.vo,新建类UserInfo.java package com.wtz.vo; /** * @author wang ...

  9. python之函数(可选参数和混合参数)

    代码举例: # 函数可选参数举例,hoppy参数可传可不传 def getinfo(name, age, hoppy=''): if hoppy: print("name:", n ...

  10. Lodop导出图片,导出单页内容的图片

    用如下语句设置图片的格式,设置导出的图片初识的默认名称,Lodop可以把打印内容导出成图片. LODOP.SET_SAVE_MODE("SAVEAS_IMGFILE_EXENAME" ...