stl, 二分查找
题目意思:
有一个整数数组 a(元素最多 n <= 2e5), 有 m 次查询 ,每次给出三个数 L, R, p;
要求在 坐标[L, R] 范围内,找到一个下标 k ,使得 a[k] != p 。每次输出k, 如果找不到,就输出 -1;
本题要点:
1、 vector v[MaxN];
用 vector 数组a的每一个数 a[i] 在数组a中的下标。 v[a[i]].push_back(i);
然后 在 v[a[i]] 里面,存的所有下标是从小到大排序的。 有序后就可以二分了。
2、一些特判。
如果 L == R, 直接看 a[L] 是否等于 p;
如果 v[p].size() == 0, 说明p根本不在a数组出现,直接输出 L;
如果 v[p].size() == 0, 并且 L < R 的情况,看看 a[L], a[R] 与 p的关系即可。
还有看看 [L, R]是否在 p 的所有的下标范围内,如果 [L, R] 超出了其范围,看看L 和 v[p][0],
R和 v[p][len - 1] 的关系即可判断。
3、普遍的情况
v[p][0] <= L && R <= v[p][len - 1]。 [L, R]在 p 的所有的下标范围内。
用 lower_bound 分别找到 L, R 在 v[p] 中出现的下标 dx , dy;
如果, p 在数组a中的 [L, R] 的范围内都出现, 必然有 v[dx] == L && v[dy] == R, 并且 R - L == dy - dx;
如果不是连续出现,满足 v[dx] == L && v[dy] == R, 而 R - L > dy - dx, 需要找到第一个 a[k] != p 的下标,
使用二分查找, 在v[p] 中,[dx, dy] 范围内,找到第一个 满足 v[p][k] - k > L - dx 的 k 坐标。
v[p][k] - 1 , 肯定是满足 a[k] != p 的下标。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int MaxN = 1e6 + 10;
int a[MaxN];
int n, m;
int l, r, p;
vector<int> v[MaxN];