NC222283. 哲学家的沉思
描述
非正常人类研究中心的哲学家牛拉底鲁曾有一句名言:“人一次也不能踏进同一条河流”,除此之外他还喜欢将连续的一段划分为若干片段。你作为中心的一名员工,为了照顾牛拉底鲁的生活起居,不得不陪他玩这样的一个游戏。
这个游戏的过程如下:牛拉底鲁会给你个数字,第个数字为。接下来他会进行次询问,每次询问将给出两个数字与,要你把区间划分为若干个片段。要求对于任意一个片段,为这个片段中的最大值。
牛拉底鲁想要最小化片段的数量,因此对于每次询问,请你回答出的最小值。
输入描述
第一行两个正整数,,其中,。
第二行个正整数,。
接下来行,每行两个正整数与,其中。
输出描述
对每次询问输出的最小值。
示例1
输入:
5 2 2 5 4 3 6 3 5 1 2
输出:
2 2
说明:
对于询问1,可以把[3,5]划分为[3,4],[5,5]。
对于询问2,可以把[1,2]划分为[1,1],[2,2]。
示例2
输入:
3 2 2 2 3 1 2 1 3
输出:
1 2
说明:
对于询问1,可以把[1,2]划分为[1,2]。
对于询问2,可以把[1,3]划分为[1,2],[3,3]。
C++ 解法, 执行用时: 66ms, 内存消耗: 9628K, 提交时间: 2021-06-25 22:01:04
#include<bits/stdc++.h> using namespace std; int a[100005],rr[100005],st[100005][20]; int main() { int i,j,n,q,l,r,ans; scanf("%d%d",&n,&q); for(i=1;i<=n;i++)scanf("%d",&a[i]); st[n][0]=rr[n]=n+1; for(i=n-1;i>=1;i--) { for(j=i+1;j!=n+1&&a[j]<=a[i];j=rr[j]); rr[i]=st[i][0]=j; } for(i=1;i<=17;i++) { for(j=1;j<=n;j++) { if(st[j][i-1]>n)st[j][i]=1e9; else st[j][i]=st[st[j][i-1]][i-1]; } } while(q--) { scanf("%d%d",&l,&r),ans=0; for(i=17;i>=0;i--)if(st[l][i]<=r)l=st[l][i],ans|=(1<<i); printf("%d\n",ans+1); } }