C - Not Equal on a Segment

主要是用线段树维护区间的最大最小值
然后判断最大值和最小值以及要查询的值的关系
我主要是用一个结构体去保存一个节点的信息
需要保存的有最大值,最小值,最大值的位置,最小值的位置

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <bitset>
#include <map>

#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define mem(i,a) memset(i,a,sizeof(i))
#define rson mid+1,r,rt<<1|1
#define lson l,mid,rt<<1

#define mp make_pair
#define ll long long
#define LL long long
using namespace std;
template <typename T>inline void read(T &_x_){
    _x_=0;bool f=false;char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=!f;ch=getchar();}
    while ('0'<=ch&&ch<='9') {_x_=_x_*10+ch-'0';ch=getchar();}
    if(f) _x_=-_x_;
}
const double eps = 0.0000001;
const int maxn = 2e5+7;
const int mod = 1e9+7;

int n,m,x,a[maxn<<2];
struct node{
    int mx,mxpos;
    int mi,mipos;
}tr[maxn<<2];

void pushup(int rt){
    if(tr[rt<<1].mi<tr[rt<<1|1].mi){
        tr[rt].mi=tr[rt<<1].mi;
        tr[rt].mipos=tr[rt<<1].mipos;
    }else{
        tr[rt].mi=tr[rt<<1|1].mi;
        tr[rt].mipos=tr[rt<<1|1].mipos;
    }
    if(tr[rt<<1].mx>tr[rt<<1|1].mx){
        tr[rt].mx=tr[rt<<1].mx;
        tr[rt].mxpos=tr[rt<<1].mxpos;
    }else{
        tr[rt].mx=tr[rt<<1|1].mx;
        tr[rt].mxpos=tr[rt<<1|1].mxpos;
    }
}

void build(int l,int r,int rt){
    if(l==r){
        read(a[l]);
        tr[rt].mi = tr[rt].mx = a[l];
        tr[rt].mipos = tr[rt].mxpos = l;
        return;
    }
    int mid=(l+r)/2;
    build(lson);
    build(rson);
    pushup(rt);
}

int querym(int l,int r,int rt,int L,int R){
    if(l>=L&&r<=R){
        return tr[rt].mxpos;
    }
    int mid=(l+r)/2;
    int x=-1,y=-1;
    if(mid>=L) x=querym(lson,L,R);
    if(mid<R) y=querym(rson,L,R);
    if(x!=-1&&y!=-1){
        if(a[x]>a[y])return x;
        else return y;
    }else return max(x,y);
}

int queryi(int l,int r,int rt,int L,int R){
    if(l>=L&&r<=R){
        return tr[rt].mipos;
    }
    int mid=(l+r)/2;
    int x=-1,y=-1;
    if(mid>=L) x=queryi(lson,L,R);
    if(mid<R) y=queryi(rson,L,R);
    if(x!=-1&&y!=-1){
        if(a[x]>a[y])return y;
        else return x;
    }else return max(x,y);
}

int main(){
    read(n),read(m);
    build(1,n,1);
    FOR(i,1,m){
        int x,y,z;
        read(x),read(y),read(z);
        int mx = querym(1,n,1,x,y);
        int mi = queryi(1,n,1,x,y);
        if(a[mi]==a[mx]&&a[mi]==z)printf("-1\n");
        else{
            if(a[mi]!=z)printf("%d\n",mi);
            else printf("%d\n",mx);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值