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"); } }