类似RMQ问题
用dp[i][j]表示[i-1, i+(1<<j))这个区间内任意一个下标k,使num[k] != num[k-1],先用ST算法对dp数组进行预处理,
对于给定的区间l, r, 和x,
1.l == r则直接判断num[l]和x是否相等.
2.l != r 用dp数组查询[l+1, r]中是否存在k, 使得num[k] != num[k-1],然后再用x和num[k]与num[k-1]比较
#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
int dp[maxn][20], num[maxn];
int n, m;
void RMQ(){
for(int i = 1; (1<<i) <= n; i++)
for(int j = 2; (j + (1<<i)) <= n+1; j++){
int k1 = dp[j][i-1], k2 = dp[j+(1<<(i-1))][i-1];
if(num[k1] != num[k1-1])
dp[j][i] = dp[j][i-1];
else
dp[j][i] = dp[j+(1<<(i-1))][i-1];
}
}
int Query(int l, int r){
int k = 0;
while(1<<(k+1) <= r - l + 1)
k++;
int k1 = dp[l][k], k2 = dp[r-(1<<k)+1][k];
if(num[k1] != num[k1-1])
return k1;
else
return k2;
}
int main(){
// freopen("in.txt", "r", stdin);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
scanf("%d", num+i);
dp[i][0] = i;
}
RMQ();
int l, r, x;
while(m--){
scanf("%d%d%d", &l, &r, &x);
if(r == l){
if(num[l] != x)
printf("%d\n", l);
else
puts("-1");
}
else if(l != r){
int k = Query(l+1, r);
if(num[k] != x)
printf("%d\n", k);
else if(num[k-1] != x)
printf("%d\n", k-1);
else
puts("-1");
}
}
return 0;
}