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