C. Not Equal on a Segment (Thinking + interval to find subscripts with different numbers)

https://codeforces.com/problemset/problem/622/C


Ideas:

I began to think of the Mo team offline.

The point of thinking is to find special maximum and minimum values. If the two are the same, it means that there is only one number. It must be impossible. Otherwise, just choose one of them. Then on the line segment tree

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
typedef pair<LL,LL>P;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
struct Tree{
   LL l,r,maxval,maxpos,minval,minpos;
}tree[maxn*4];
LL a[maxn];
void push_up(LL p){
    if(tree[p].maxval<tree[p*2].maxval) tree[p].maxval=tree[p*2].maxval,tree[p].maxpos=tree[p*2].maxpos;
    if(tree[p].maxval<tree[p*2+1].maxval) tree[p].maxval=tree[p*2+1].maxval,tree[p].maxpos=tree[p*2+1].maxpos;
    if(tree[p].minval>tree[p*2].minval) tree[p].minval=tree[p*2].minval,tree[p].minpos=tree[p*2].minpos;
    if(tree[p].minval>tree[p*2+1].minval) tree[p].minval=tree[p*2+1].minval,tree[p].minpos=tree[p*2+1].minpos;
}
void build(LL p,LL l,LL r){
    tree[p].l=l;tree[p].r=r;tree[p].maxpos=-1;tree[p].maxval=-1;tree[p].maxval=-1;tree[p].minval=0x3f3f3f3f;
    if(l==r){tree[p].maxval=tree[p].minval=a[l];tree[p].minpos=tree[p].maxpos=l;return;}
    LL mid=(l+r)>>1;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    push_up(p);
}
P mquery(LL p,LL l,LL r){
  if(l<=tree[p].l&&r>=tree[p].r){
     P A={tree[p].maxval,tree[p].maxpos};
     return A;
  }
  LL mid=(tree[p].l+tree[p].r)>>1;
  P ans={0,0};
  if(l<=mid){
    P temp=mquery(p*2,l,r);
    if(ans.first<temp.first) ans=temp;
  }
  if(r>mid){
    P temp=mquery(p*2+1,l,r);
    if(ans.first<temp.first) ans=temp;
  }
  return ans;
}
P squery(LL p,LL l,LL r){
  if(l<=tree[p].l&&r>=tree[p].r){
    P A={tree[p].minval,tree[p].minpos};
    return A;
  }
  LL mid=(tree[p].l+tree[p].r)>>1;
  P ans={0x3f3f3f3f,0x3f3f3f3f};
  if(l<=mid){
    P temp=squery(p*2,l,r);
    if(temp.first<ans.first) ans=temp;
  }
  if(r>mid){
    P temp=squery(p*2+1,l,r);
    if(temp.first<ans.first) ans=temp;
  }
  return ans;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m;cin>>n>>m;
  for(LL i=1;i<=n;i++) cin>>a[i];
  build(1,1,n);
  while(m--){
    LL l,r,x;cin>>l>>r>>x;
    P ans1=mquery(1,l,r);
    if(ans1.first!=x){
        cout<<ans1.second<<"\n";
        continue;
    }
    P ans2=squery(1,l,r);
    if(ans2.first!=x){
        cout<<ans2.second<<"\n";
        continue;
    }
    cout<<"-1"<<"\n";
  }
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/114987945