列表

详情


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);
	}
}

上一题