C.与众不同 (RMQ + 思维)

题目链接

题意:给你一个序列,长度为2e5,序列元素的取值范围【-1e6,1e6】。有q次查询,每次查询l,r,问l到r中完美序列的最大值,完美序列的定义是:一段连续的序列满足序列中的数互不相同。

思路:这个居然可以用RMQ,实在是太神奇了。

首先:我用一个a数组记录i位置往前的第一个非法位置,什么意思呢?

  序列:1 3 2 5 2 2

a数组:0 0 0 0 3 5

对于第一个位置来说,往前没有非法位置,为0,对于最后一个元素来说,往前第一个非法位置是5.

那么:st【i】【0】的定义就是,以i位置为右端点,往前的完美序列的长度,st【i】【1】就是第 i 位置和第 i+1位置中 分别以他们为右端点的完美序列的长度。

那么,我们怎么利用RMQ来求出答案呢。

分情况:如果,a【r】< l,意味着第 r 个位置往前的第一个非法位置不在询问的区间中,所以,答案就是区间长度。否则,在a数组中找到第一个往前非法位置大于等于 l - 1 的位置记为 p ,那么 p 往后的那些位置的非法位置必定大于等于p,往前的那些位置的非法位置必定小于等于p,那么答案就在 p - l 与 区间【p,r】的st值之中


using namespace std;

const int base = 1e6+10,maxn = 2e5+10;
int pre[base*4+100];
int st[maxn][25],a[maxn];

int solve(int l,int r)
{
	int k = log(r-l+1)/log(2);
	int ans = max(st[l][k],st[r-(1<

 

你可能感兴趣的:(RMQ)