bzoj千题计划165:bzoj5127: 数据校验

Posted 日拱一卒 功不唐捐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj千题计划165: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");
    }
}

 

以上是关于bzoj千题计划165:bzoj5127: 数据校验的主要内容,如果未能解决你的问题,请参考以下文章

bzoj千题计划214:bzoj3589: 动态树

bzoj千题计划197:bzoj4247: 挂饰

bzoj千题计划118:bzoj1028: [JSOI2007]麻将

bzoj千题计划144:bzoj1176: [Balkan2007]Mokia

bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

bzoj千题计划142:bzoj3144: [Hnoi2013]切糕