bzoj5127: 数据校验

http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf

区间的任意一个子区间都满足值域连续

等价于

区间任意一个长为2的子区间都满足值域连续

区间任意相邻的两个数 大的 减 小的 <=1

线段树维护即可

#include<cstdio>
#include<iostream>
#include<algorithm>
 
using namespace std;
 
#define N 100001
 
int a[N];
 
bool ok[N<<2];
 
bool ans;
 
void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}
 
void build(int k,int l,int r)
{
    if(l==r) 
    {
        ok[k]=(max(a[l],a[l+1])-min(a[l],a[l+1])<=1);
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    ok[k]=ok[k<<1]&ok[k<<1|1];
}
 
void query(int k,int l,int r,int opl,int opr)
{
    if(l>=opl && r<=opr) 
    {
        ans&=ok[k];
        return;
    }
    int mid=l+r>>1;
    if(opl<=mid) query(k<<1,l,mid,opl,opr);
    if(opr>mid) query(k<<1|1,mid+1,r,opl,opr);
}
 
int main()
{
    int n,m;
    read(n); read(m);
    for(int i=1;i<=n;++i) read(a[i]);
    if(n==1)
    {
        while(m--) puts("YES");
        return 0;
    }
    build(1,1,n-1);
    int l,r;
    while(m--)
    {
        read(l); read(r);
        if(l==r) 
        {
            puts("YES");
            continue;
        }
        ans=true;
        query(1,1,n-1,l,r-1);
        puts(ans ? "YES" : "NO");
    }
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8148911.html