题解:把每一个位置接下来第一个“和这个位置的数字不同的位置”记录下来,每次查询就是不相等就直接返回,相等就判断一下下一个位置在不在查询的区间里面就可以了。
考场上脑子抽了以为这个会超时,所以写了一棵线段树来维护……感觉自己没救了QwQ
代码如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#define lson (nd<<1)
#define rson (nd<<1|1)
using namespace std;
struct node{
int ss;
bool flag;
}t[1000010];
int n,m;
int a[200010];
void build(int L,int R,int nd)
{
if(L==R){t[nd].ss=a[L];t[nd].flag=1;return ;}
int mid=(L+R)>>1;
build(L,mid,lson);build(mid+1,R,rson);
if(t[lson].flag&&t[rson].flag&&t[lson].ss==t[rson].ss){t[nd].flag=1;t[nd].ss=t[lson].ss;}
else t[nd].flag=0;
}
int find(int L,int R,int l,int r,int nd,int x)
{
if(l<=L&&R<=r)
{
if(t[nd].flag&&t[nd].ss==x) return -1;
if(t[nd].flag&&t[nd].ss!=x) return L;
}
int mid=(L+R)>>1,la,ra;
if(l<=mid)
{
la=find(L,mid,l,r,lson,x);
if(la!=-1) return la;
}
if(r>mid)
{
la=find(mid+1,R,l,r,rson,x);
if(la!=-1) return la;
}
return -1;
}
int main()
{
int l,r,x;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,n,1);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&l,&r,&x);
printf("%d\n",find(1,n,l,r,1,x));
}
return 0;
}