Zeratul的完美区间(线段树||RMQ模板题)

原题大意:原题链接

给定元素无重复数组,查询给定区间内元素是否连续

解体思路:由于无重复元素,所以如果区间内元素连续,则该区间内的最大值和最小值之差应该等于区间长度(r-l)

解法一:线段树(模板题)

#include<cstdio>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e5+10;
int va,curmi,curma;
int mi[4*maxn],ma[4*maxn];
void Build(int p,int l,int r)
{
    if(l==r){
        scanf("%d",&va);
        mi[p]=ma[p]=va;
        return;
    }
    int mid=(l+r)/2;
    Build(2*p,l,mid);
    Build(2*p+1,mid+1,r);
    mi[p]=min(mi[2*p],mi[2*p+1]);
    ma[p]=max(ma[2*p],ma[2*p+1]);
}
void Query(int p,int l,int r,int ll,int rr)
{
    if(ll<=l&&r<=rr){
        curmi=min(curmi,mi[p]);
        curma=max(curma,ma[p]);
        return;
    }
    int mid=(l+r)/2;
    if(ll<=mid)
        Query(2*p,l,mid,ll,rr);
    if(rr>mid)
        Query(2*p+1,mid+1,r,ll,rr); 
}
int main()
{
    int n,m,q,l,r;
    scanf("%d",&n);
    Build(1,1,n);
    scanf("%d",&q);
    while(q--){
        scanf("%d%d",&l,&r);
        curmi=inf,curma=-inf;
        Query(1,1,n,l,r);
        if(curma-curmi==r-l) puts("YES");
        else puts("NO");
    }
} 

 解法二:RMQ(模板题)

#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int n,q,l,r,va,curmi,curma;
int mi[maxn][20],ma[maxn][20]; 

void Rmq_Precede()
{
    for(int j=1;(1<<j)<=n;j++){//长度最长为log2n 
        for(int i=1;i+(1<<j)-1<=n;i++){//最后一个元素编号为i+(1<<j)-1 
            mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
            ma[i][j]=max(ma[i][j-1],ma[i+(1<<(j-1))][j-1]);
        }
    }
}
void Rmq_Query(int l,int r)
{
    int k=log2(r-l+1);
    curmi=min(mi[l][k],mi[r-(1<<k)+1][k]);
    curma=max(ma[l][k],ma[r-(1<<k)+1][k]);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&va);
        mi[i][0]=ma[i][0]=va;
    }
    Rmq_Precede();
    scanf("%d",&q);
    while(q--){
        scanf("%d%d",&l,&r);
        Rmq_Query(l,r);
        if(curma-curmi==r-l) puts("YES");
        else puts("NO");
    }
}

 

posted @ 2017-03-10 22:13  despair_ghost  阅读(361)  评论(0编辑  收藏  举报