CF 279C Ladder(区间问题)

77 阅读2分钟
  • You've got an array, consisting of n integers a1, a2, ..., a**n. Also, you've got m queries, the i-th query is described by two integers l**i, r**i. Numbers l**i, r**i define a subsegment of the original array, that is, the sequence of numbers ali, ali + 1, ali + 2, ..., ari. For each query you should check whether the corresponding segment is a ladder.

    A ladder is a sequence of integers b1, b2, ..., b**k, such that it first doesn't decrease, then doesn't increase. In other words, there is such integer x (1 ≤ x ≤ k), that the following inequation fulfills: b1 ≤ b2 ≤ ... ≤ b**x ≥ b**x + 1 ≥ b**x + 2... ≥ b**k. Note that the non-decreasing and the non-increasing sequences are also considered ladders.

Input

  • The first line contains two integers n and m (1 ≤ n, m ≤ 105) — the number of array elements and the number of queries. The second line contains the sequence of integers a1, a2, ..., a**n (1 ≤ a**i ≤ 109), where number a**i stands for the i-th array element.

    The following m lines contain the description of the queries. The i-th line contains the description of the i-th query, consisting of two integers l**ir**i (1 ≤ l**i ≤ r**i ≤ n) — the boundaries of the subsegment of the initial array.

    The numbers in the lines are separated by single spaces.

Output

  • Print m lines, in the i-th line print word "Yes" (without the quotes), if the subsegment that corresponds to the i-th query is the ladder, or word "No" (without the quotes) otherwise.

Example

  • Input

    8 6
    1 2 1 3 3 5 2 1
    1 3
    2 3
    2 4
    8 8
    1 4
    5 8
    

    Output

    Yes
    Yes
    No
    Yes
    No
    Yes
    

    \

    题意:

    对于一段序列,要求刚开始不能递减,之后不能递增。换言之,只能有一个波峰,不能有波谷,可以是一条平平的线。

    思路:

    算出所求区间左端点向右延伸的距离,右段点向左延伸的距离。两段距离相加,若大于等于区间长度就是yes。

    #include<iostream>
    #include<cstdio> 
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int mx = 1e5 + 5;
    int num[mx], le[mx], ri[mx];
    int n, m;
    int main(){
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i++)
    		scanf("%d", &num[i]); 
    	int a, b ,flag;
    	ri[n] = 0;
    	for(int i = n -1; i >= 1; i--){    //向右延伸的长度 
    		if(num[i] <= num[i + 1])      //等于的时候也是可以延伸的 
    			ri[i] = ri[i + 1] + 1;
    		else ri[i] = 0;
    	}
    	
    	le [1] = 0;
    	for(int i = 2; i <= n; i++){
    		if(num[i] <= num[i -1])     //向左延伸距离 
    			le[i] = le[i -1] + 1;
    		else le[i] = 0; 
    	} 		
    	
    	while(m--){
    		scanf("%d%d", &a, &b);
    		//cout<<ri[a]<<endl;
    	//	cout<<le[b]<<endl;
    		if( (ri[a] + le[b]) >= (b - a))
    			puts("Yes");
    		else 
    			puts("No"); 
    	}
    	
    	return 0;
    }
    


    \

本文已参与「新人创作礼」活动,一起开启掘金创作之路