CF1696D Permutation Graph 题解

可能更好的阅读体验

题目传送门

题目大意

给定一个长度为 n 排列 a
定义 mn(i,j)=mink=ijak,mx(i,j)=maxk=ijak
然后建立一个 n 个节点图,如果 mn(i,j)=ai,mx(i,j)=aj 或者 mn(i,j)=aj,mx(i,j)=ai,那么就在 i,j 之间连一条无向边。
1 号点到 n 号点的最短路。
n105

题目解析

首先根据连边的条件我们发现在最短路径中肯定不会往回走。
并且根据定义,如果 u<v<w u,vu,w 之间有边,那么 v,w 之间也肯定有边,所以每次尽量往编号大的节点走。
问题就转化为了求与当前点有边相连的编号最大的点。

考虑利用单调栈预处理出每个节点有边第一个比它大/小的点,然后往右跳,并且用线段树 / ST 表求出这一段的最值来判断当前的左端点是否为这个区间的最值即可。
时间复杂度 O(nlogn)

int n,ln,a[maxn],rx[maxn],ry[maxn],st[maxn],top;
int minx[maxn<<2],maxx[maxn<<2],L,R;
void up(int rt){ minx[rt]=mmin(minx[rt<<1],minx[rt<<1|1]); maxx[rt]=mmax(maxx[rt<<1],maxx[rt<<1|1]); }
void build(int l,int r,int rt){
if(l==r){ minx[rt]=maxx[rt]=a[l]; return; } int mid=(l+r)>>1;
build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); up(rt); return;
}
int findmin(int l,int r,int rt){
if(L<=l&&r<=R) return minx[rt]; int mid=(l+r)>>1,res=INF;
if(mid>=L) res=mmin(res,findmin(l,mid,rt<<1));
if(mid<R) res=mmin(res,findmin(mid+1,r,rt<<1|1));
return res;
}
int findmax(int l,int r,int rt){
if(L<=l&&r<=R) return maxx[rt]; int mid=(l+r)>>1,res=-1;
if(mid>=L) res=mmax(res,findmax(l,mid,rt<<1));
if(mid<R) res=mmax(res,findmax(mid+1,r,rt<<1|1));
return res;
}
void work(){
n=read(); ln=ceil(log2(n)); int i; for(i=1;i<=n;i++) a[i]=read(),rx[i]=ry[i]=0; build(1,n,1);
top=1; st[top]=1; for(i=2;i<=n;i++){ while(a[st[top]]<a[i]&&top) rx[st[top]]=i,top--; st[++top]=i; }
top=1; st[top]=1; for(i=2;i<=n;i++){ while(a[st[top]]>a[i]&&top) ry[st[top]]=i,top--; st[++top]=i; }
int now=1,ri=1,cnt=0;
while(1){
now=ri; if(ri==n) break; ri=now+1; cnt++;
if(a[now]<a[ri]) while(rx[ri]){ L=now; R=rx[ri]; if(findmin(1,n,1)!=a[now]) break; ri=rx[ri]; }
else while(ry[ri]){ L=now; R=ry[ri]; if(findmax(1,n,1)!=a[now]) break; ri=ry[ri]; }
} print(cnt),pc('\n');
}
int main(){
//freopen("1.in","r",stdin);
//freopen(".out","w",stdout)
int T=read(); while(T--) work(); return 0;
}
posted @   jiangtaizhe001  阅读(116)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示