F题:等差区间(RMQ||线段树)

原题大意:原题链接  题解链接

给定一个长为n的数组元素和q次区间[l,r]询问,判断区间[l,r]内元素排序后能否构成等差数列

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int n,q,l,r;
int a[maxn],temp[1000010];
int mi[maxn][20],ma[maxn][20];
int gd[maxn][20],po[maxn][20];

int gcd(int a,int b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}
int ggg(int a,int b)
{
    if(a==0||b==0) return 0;
    return gcd(a,b);
}
void Rmq_Precede()
{
    for(int j=1;(1<<j)<=n;j++){
        for(int i=1;i+(1<<j)-1<=n;i++){
            ma[i][j]=max(ma[i][j-1],ma[i+(1<<(j-1))][j-1]);
            mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
            gd[i][j]=ggg(gd[i][j-1],gd[i+(1<<(j-1))][j-1]);
            po[i][j]=max(po[i][j-1],po[i+(1<<(j-1))][j-1]);
        }
    }
}
int Rmq_Max(int l,int r)
{
    int k=log2(r-l+1);
    return max(ma[l][k],ma[r-(1<<k)+1][k]);
}
int Rmq_Min(int l,int r)
{
    int k=log2(r-l+1);
    return min(mi[l][k],mi[r-(1<<k)+1][k]);
}
int Rmq_Gcd(int l,int r)
{
    int k=log2(r-l+1);
    return gcd(gd[l][k],gd[r-(1<<k)+1][k]);
}
int Rmq_Pos(int l,int r)
{
    int k=log2(r-l+1);
    return max(po[l][k],po[r-(1<<k)+1][k]);
}

int main()
{
    while(scanf("%d%d",&n,&q)!=EOF){
        memset(temp,0,sizeof(temp));
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            po[i][0]=temp[a[i]];//如果有重复元素,则temp[a[i]]会被覆盖 
            temp[a[i]]=i;
            mi[i][0]=ma[i][0]=a[i];
            gd[i][0]=abs(a[i]-a[i-1]);
        }
        Rmq_Precede();
        while(q--){
            scanf("%d%d",&l,&r);
            if(l==r||l+1==r) {printf("Yes\n"); continue;}
            int curmi=Rmq_Min(l,r),curma=Rmq_Max(l,r),curgd=Rmq_Gcd(l+1,r);
            if(Rmq_Pos(l,r)>=l){//判重,如果数组中有相同元素,一定会执行此步骤
                if(curmi==curma){printf("Yes\n"); continue;}
                else{printf("No\n"); continue;}  
            }
            if(curgd*(r-l)==curma-curmi){printf("Yes\n"); continue;}
            else{printf("No\n"); continue;}
        }
    }
    return 0;
}

 

测试很多数据均无误,但是提交后却一直WA,望各位大佬指点

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 100010
#define inf 0x3f3f3f3f
using namespace std;
int temp[1000010];
int i=1,po,mi,ma,gd;
int segmin[4*maxn];
int segmax[4*maxn];
int a[maxn],d[maxn];
int g[4*maxn],segpos[4*maxn];

int gcd(int a,int b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}
int ggg(int a,int b)
{
    if(a==0||b==0) return 0;
    return gcd(a,b);
}
void Build(int p,int l,int r)
{
    if(l==r){
        scanf("%d",&a[i]);
        segmin[p]=segmax[p]=a[i];
        segpos[p]=temp[a[i]];
        temp[a[i]]=i;
        i++;
        return;
    }
    int mid=(l+r)/2;
    Build(2*p,l,mid);
    Build(2*p+1,mid+1,r);
    segpos[p]=max(segpos[2*p],segpos[2*p+1]);
    segmin[p]=min(segmin[2*p],segmin[2*p+1]);
    segmax[p]=max(segmax[2*p],segmax[2*p+1]);
}
void Query_val(int p,int l,int r,int ll,int rr)
{
    if(ll<=l&&r<=rr){
        po=max(po,segpos[p]);
        mi=min(mi,segmin[p]);
        ma=max(ma,segmax[p]);
        return;
    }
    int mid=(l+r)/2;
    if(ll<=mid)
        Query_val(2*p,l,mid,ll,rr);
    if(rr>mid)
        Query_val(2*p+1,mid+1,r,ll,rr);
}
void Create(int p,int l,int r)
{
    if(l==r){
        g[p]=d[l];
        return;
    }
    int mid=(l+r)/2;
    Create(2*p,l,mid);
    Create(2*p+1,mid+1,r);
    g[p]=ggg(g[2*p],g[2*p+1]);
}
void Query_gcd(int p,int l,int r,int ll,int rr)
{
    if(ll<=l&&r<=rr){
        gd=ggg(gd,g[p]);
        return;
    }
    int mid=(l+r)/2;
    if(ll<=mid)
        Query_gcd(2*p,l,mid,ll,rr);
    if(rr>mid)
        Query_gcd(2*p+1,mid+1,r,ll,rr);
}

int main()
{
    int n,q,l,r;
    while(scanf("%d%d",&n,&q)!=EOF){
        memset(temp,0,sizeof(temp));
        Build(1,1,n);
        /*for(int i=1;i<=9;i++){
            printf("%d\n",segpos[i]);
            printf("%d %d\n",segmin[i],segmax[i]);
        }*/
        for(int i=1;i<n;i++)
            d[i]=abs(a[i]-a[i-1]);
        Create(1,1,n-1);
        while(q--){
            scanf("%d%d",&l,&r);
            if(l==r||l+1==r){
                printf("Yes\n");
                continue;
            }
            po=-1,mi=inf,ma=-inf;
            Query_val(1,1,n,l,r);
            if(po>=l){
                if(mi==ma) {printf("Yes\n"); continue;}
                else {printf("No\n"); continue;}
            }
            gd=d[l+1];
            Query_gcd(1,1,n-1,l+1,r);
            if(gd*(r-l)==ma-mi) printf("Yes\n");
            else printf("No\n"); 
        }
    }
}

 

posted @ 2017-03-08 11:05  despair_ghost  阅读(277)  评论(0编辑  收藏  举报