Codeforces 622C Not Equal on a Segment(线段树)

题目链接:

http://codeforces.com/contest/622/problem/C

题目大意:

给一个长为n 的序列,m个询问。每次询问一个区间[l,r]和数x。问这个区间里面任意一个不是x的数的位置。

范围:

n,m<=2*10^5。

思路:

可以考虑线段树。利用线段树维护区间上的最大值和最小值。每次询问时看当前区间上的最大和最小值是否与x不同,如果不同,就先往左子树看,如果左子树上面的最大最小值和x相同,就往右子树去看。直到叶子结点,就是答案,否则就是-1。

代码:

#include
#include
#include
#include
#define M 200005
using namespace std;
int max(int a,int b)
{
    return a>b?a:b;
}
int min(int a,int b)
{
    return a>1;
    if(l==r){
        tree[i].ma=tree[i].mi=a[tree[i].l];
        return;
    }
    build(l,mid,i<<1);
    build(mid+1,r,i<<1|1);
    pushup(i);
    return;
}
int ans,f;
void query(int l,int r,int i,int z)
{
 if(f)return;
    if(tree[i].l==tree[i].r){
        if(tree[i].ma!=z){f=1;ans=tree[i].l;}
        else ans=-1;
        return;
    }
             int mid=tree[i].l+tree[i].r>>1;
    if(tree[i].ma!=z||tree[i].mi!=z){
         if(r<=mid)query(l,r,i<<1,z);
    else if(l>mid) query(l,r,i<<1|1,z);
  else {
    query(l,mid,i<<1,z);
    query(mid+1,r,i<<1|1,z);
    }


  }
  else {
    ans=-1;
  }
}
int main()
{
    int i,j,k,l,r,m,x;
    while(~(scanf("%d%d",&n,&m)))
    {
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
            build(1,n,1);
            while(m--)
            {
                f=0;
                scanf("%d%d%d",&l,&r,&x);
                query(l,r,1,x);
                       printf("%d\n",ans);
            }
    }
}


你可能感兴趣的:(线段树,数据结构----------)