码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 279C C. Ladder(rmq+预处理)

时间:2015-09-17 11:55:28      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:codeforces   dp   rmq   

题目连接:

codeforces 279C


题目大意:

给出一个序列,m次查询,每次给出一个子串,问这个子串是否满足,中间能够找到一个元素,让这个元素作为前后分别单调的分界.


题目分析:

  • 首先对于每次查询,我们知道分界一定是最大的元素,所以我们可以用rmq预处理出区间最大。
  • 然后为了判断这个区间是否能够通过最大的元素作为分界点而前后单调,我们可以通过预处理,正向和反向分别扫一遍,记录某一个点的为最大元素的能够向左和向右得到的最长的单调子串的长度,然后每次只需要O(1)的判断就可以,判断当前元素最为最大的元素延展的最大的子串是否覆盖当前查询的子串。如果是,那么结果就是YES,否则是No

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define MAX 100007

using namespace std;

typedef pair<int,int> PII;
int n,m,a[MAX],lef[MAX],rig[MAX],dp[MAX][30],ans[MAX][30];

void make ( )
{
    for ( int i = 1 ; i <= n ; i++ )
    {
        dp[i][0] = a[i];
        ans[i][0] = i;
    }
    for ( int j = 1 ; (1<<j) <= n ; j++ )
        for ( int i = 1 ; i+(1<<j)-1 <= n ; i++ )
        {
            dp[i][j] = max ( dp[i][j-1] , dp[i+(1<<(j-1))][j-1]);
            if ( dp[i][j-1] == dp[i][j] )
                ans[i][j] = ans[i][j-1];
            else ans[i][j] = ans[i+(1<<(j-1))][j-1];
        }
    for ( int i = 1 ; i <= n ; i++ )
        lef[i] = rig[i] = 1;
    for ( int i = 2 ; i <= n ; i++ )
        if ( a[i-1] <= a[i] )
            lef[i] = lef[i-1]+1;
    for ( int i = n-1 ; i >= 1 ; i-- )
        if ( a[i+1] <= a[i] )
            rig[i] = rig[i+1]+1;
}

PII query ( int l , int r )
{
    int k = (int)((log((r-l+1)*1.0))/log(2.0));
    int maxn;
    int temp;
    maxn = max ( dp[l][k] , dp[r-(1<<k)+1][k] );
    if ( maxn == dp[l][k] ) temp = ans[l][k];
    else temp = ans[r-(1<<k)+1][k];
    return make_pair ( maxn , temp );
}

int main ( )
{
    while ( ~scanf ( "%d%d" , &n , &m ))
    {
        for ( int i = 1 ; i <= n ; i++ )
            scanf ( "%d" , &a[i] );
        make();
        while ( m-- )
        {
            int l,r;
            scanf ( "%d%d" , &l , &r );
            PII temp = query ( l , r );
            int x = temp.second;
            //cout << x << " " << lef[x] << " " << rig[x] << endl;
            if ( x-lef[x]+1 <= l && x+rig[x]-1 >= r )
                puts ( "Yes" );
            else puts ("No");
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

codeforces 279C C. Ladder(rmq+预处理)

标签:codeforces   dp   rmq   

原文地址:http://blog.csdn.net/qq_24451605/article/details/48518661

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!