思路:
直接二分最东和最西能到达的位置,然后可以一直在这两个点之间一直跳,所以直接用%减少运算
c o d e code code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 2e5 + 10;
int n, m, b[MAXN], c[MAXN];
struct node {
int x, id;
}a[MAXN];
bool cmp(node x, node y) {
return x.x < y.x;
}
int erfen1(int l, int r, int x) {
while(l <= r) {
int mid = l + r >> 1;
if(b[mid] <= x) l = mid + 1;
else r = mid - 1;
}
return l - 1;
}
int erfen2(int l, int r, int x) {
while(l <= r) {
int mid = l + r >> 1;
if(b[mid] >= x) r = mid - 1;
else l = mid + 1;
}
return r + 1;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) {
scanf("%d", &a[i].x);
a[i].id = i;
}
sort(a + 1, a + 1 + n, cmp);
for(int i = 1; i <= n; i ++) b[i] = a[i].x, c[a[i].id] = i;
while(m --) {
int x, l;
scanf("%d%d", &x, &l);
x = c[x];
bool flag = 1;
while(flag) {
flag = 0;
int right = erfen1(x, n, a[x].x + l);
if(right < x) break;
right = min(n, right);
if(right != x) flag = 1;
l -= a[right].x - a[x].x;
x = right;
int left = erfen2(1, x, a[x].x - l);
left = max(1, left);
if(left != x) flag = 1;
l -= a[x].x - a[left].x;
x = left;
if(b[right] - b[left] == 0) continue;
l %= (b[right] - b[left]) * 2;
}
printf("%d\n", a[x].id);
}
return 0;
}