标签:codeforces dp rmq
给出一个序列,m次查询,每次给出一个子串,问这个子串是否满足,中间能够找到一个元素,让这个元素作为前后分别单调的分界.
#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