ioi2018集训队自选题:最短路练习题
题意:链接
定义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集训队自选题:最短路练习题的更多相关文章
- 简单数据结构题(from 钟子谦——IOI2018集训队自选题)
简单数据结构题(from 钟子谦--IOI2018集训队自选题) 试题描述 给一棵 \(n\) 个点的树,点权开始为 \(0\) ,有 \(q\) 次操作,每次操作是选择一个点,把周围一圈点点权 \( ...
- 【BZOJ2622】[2012国家集训队测试]深入虎穴 次短路
[BZOJ2622][2012国家集训队测试]深入虎穴 Description 虎是中国传统文化中一个独特的意象.我们既会把老虎的形象用到喜庆的节日装饰画上,也可能把它视作一种邪恶的可怕的动物,例如“ ...
- 【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\)两点 ...
- 8月清北学堂培训 Day5
今天是杨思祺老师的讲授~ 最短路练习题: POJ 1125 Stockbroker Grapevine 有 N 个股票经济人可以互相传递消息,他们之间存在一些单向的通信路径.现在有一个消息要由某个人开 ...
- 【6.24校内test】T3 棠梨煎雪
[题目背景] 岁岁花藻檐下共将棠梨煎雪. 自总角至你我某日辗转天边. 天淡天青,宿雨沾襟. 一年一会信笺却只见寥寥数言. ——银临<棠梨煎雪> [问题描述] 扶苏正在听<棠梨煎雪&g ...
- 【LGR-065】洛谷11月月赛 III Div.2
临近$CSP$...... 下午打了一发月赛,感觉很爽. 非常菜的我只做了前两题......然而听说前两题人均过...... 写法不优秀被卡到$#1067$...... T1:基础字符串练习题: 前缀 ...
- BZOJ_2622_[2012国家集训队测试]深入虎穴_最短路
BZOJ_2622_[2012国家集训队测试]深入虎穴_最短路 Description 虎是中国传统文化中一个独特的意象.我们既会把老虎的形象用到喜庆的节日装饰画上,也可能把它视作一种邪恶的可怕的动物 ...
- [转] ACM中国国家集训队论文集目录(1999-2009)
国家集训队1999论文集 陈宏:<数据结构的选择与算法效率——从IOI98试题PICTURE谈起>来煜坤:<把握本质,灵活运用——动态规划的深入探讨>齐鑫:<搜索方法中的 ...
- ACM/ICPC 之 两道dijkstra练习题(ZOJ1053(POJ1122)-ZOJ1053)
两道较为典型的单源最短路径问题,采用dijkstra解法 本来是四道练习题,后来发现后面两道用dijkstra来解的话总觉得有点冗余了,因此暂且分成三篇博客(本篇以及后两篇). ZOJ1053(POJ ...
随机推荐
- CSS 尺寸 (Dimension) 实例
CSS 尺寸 (Dimension) 实例CSS 尺寸属性CSS 尺寸属性允许你控制元素的高度和宽度.同样,还允许你增加行间距. 属性 描述height 设置元素的高度.line-height 设置行 ...
- Bash 中常见的字符串操作
获取字符串长度 ${#string} MyString=abcABC123ABCabc 注意这会自动去掉字符串结尾处的空格,如果在字符串中包含空格(开头.中间或结尾),就需要使用引号把字符串包裹起来: ...
- js实现随机的四则运算题目(2)-更新界面
上次的代码提交完成后,有很多bug.比如函数会重复调用执行,每点击一次按钮都会在生成题目的下方直接生成新的题目,于是我在代码前面添加了如下的代码: function play_allE() { doc ...
- 读书笔记(chapter7)
第七章 链接 链接是将各种代码和数据部分收集起来并且组合成为一个单一文件的过程.1.这个文件可被加载到存储器并执行:2.也可以执行于加载时,也就是在程序被加载器加载到存储器并执行:3.甚至可以执行于运 ...
- A KeyValuePair in Java
A KeyValuePair in Java Programming & English tuble 元组 pair 对(两)元组 tuple 三元组 dozen 一打(12个).有 ...
- Mysql 5.7.21 设置主从库同步
主从复制条件: Mysql 单机多实例安装参考Mysql 5.7.21 设置主从库同步 下面的操作是多实例主从复制,3306为主库,3307为从库. 主库要开启log-bin,主库和从库的server ...
- [日常工作] SUSE设置上网ip地址
1. 同事搜到的命令 ifconfig eth0 10.24.25.8 netmask 255.255.0.0 up route add default gw 10.24.255.254 2. 修改 ...
- Jquery 组 checkbox双向控制与tr变色
<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8&qu ...
- [Java] Thread的start()和run()函数区别
1.start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码: 通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状 ...
- loadrunner 基础-学习笔记一
由于公司要使用loadrunner暂停学习jmeter 1 loadrunner组件: virtual user generator:录制最终用户业务流程并创建自动化性能测试脚本,vuser脚本 co ...