平面上有n个钉子,他们从1到n编号,第i个钉子的坐标是 (xi, 0)。然后我们我们把一个长度为L,带重物的绳子系到第i个钉子上(那么重物所在的坐标是(xi, -L))。然后用力将重物向右推,开始逆时针旋转。同时,如果旋转的过程中碰到其它的钉子,就会绕着那个钉子旋转。假设每个钉子都很细,重物绕着它旋转时,不影响到绳子的长度。

更一般的,如果绳子碰到多个钉子,那么它会绕着最远的那个钉子转。特殊的,如果绳子的末端碰到了一个钉子,那么也会绕着那个钉子以长度为0的绳子在转。
经过一段时间之后,重物就会一直绕着某个钉子转。
现在有m个查询,每个查询给出初始的绳子长度以及挂在哪个钉子下旋转,请找出重物最终会绕哪个钉子旋转。
样例解释:

Input
单组测试数据。 第一行包含两个整数n 和 m (1 ≤ n, m ≤ 2*10^5),表示钉子的数目以及查询的数目。 接下来一行包含n个整数 x1, x2, ..., xn ( -10^9 ≤ xi ≤ 10^9),表示每个钉子的坐标。保证输入的钉子的坐标两两不相同。 接下来m行给出查询。每行给出ai (1 ≤ ai ≤ n) 和 li(1 ≤ li ≤ 10^9),表示该查询的重物挂在第ai个钉子上,绳子长度是li。
Output
输出m行,第i行输出第i个查询的重物最终绕着哪个钉子转。
二分查找钉子然后加了点优化..
#include<iostream> #include<algorithm> #include<stdio.h> using namespace std; int ok(long long x); struct node { long long data; int id; }; bool cmp(node x,node y) { return x.data<y.data; } node s[200003]; long long s1[200003]={0}; int n=0,m=0; int jilv[3]={0}; int t=0; int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { scanf("%lld",&s[i].data); s[i].id=i; s1[i]=s[i].data; } sort(s+1,s+n+1,cmp); t=0; while(m--) { int x=0,r=0; t=0; cin>>x>>r; x=ok(s1[x]); int end=0; int sum=0; jilv[t++]=x; if(s[x].data+r<s[x+1].data||x==n) sum++; while(1) { int y=0; if(sum%2==0) { y=ok(s[x].data+r); if(s[x].data+r==s[y].data) { end=y; break; } else if(s[x].data==s[y].data) { end=y; break; } else { r=r-(s[y].data-s[x].data); x=y; } sum++; if(t<2) { jilv[t++]=x; } else { if(jilv[0]==x) { int R=abs(s[jilv[0]].data-s[jilv[1]].data); int p=r/(R); if(p&1) { r=r-p*R; x=jilv[1]; jilv[0]=x; t=1; sum++; } else { r=r-p*R; t=1; } } else { jilv[0]=jilv[1]; jilv[1]=x; } } } else { y=ok(s[x].data-r); if(y==0) { r=r-(s[x].data-s[1].data); x=1; sum++; if(t<2) { jilv[t++]=x; } else { if(jilv[0]==x) { int R=abs(s[jilv[0]].data-s[jilv[1]].data); int p=r/(R); if(p&1) { r=r-p*R; x=jilv[1]; jilv[0]=x; t=1; sum++; } else { r=r-p*R; t=1; } } else { jilv[0]=jilv[1]; jilv[1]=x; } } continue; } if(s[x].data-r==s[y].data) { end=y; break; } else if(s[x].data==s[y+1].data) { end=x; break; } else { r=r-(s[x].data-s[y+1].data); x=y+1; } sum++; if(t<2) { jilv[t++]=x; } else { if(jilv[0]==x) { int R=abs(s[jilv[0]].data-s[jilv[1]].data); int p=r/(R); if(p&1) { r=r-p*R; x=jilv[1]; jilv[0]=x; t=1; sum++; } else { r=r-p*R; t=1; } } else { jilv[0]=jilv[1]; jilv[1]=x; } } } } printf("%d\n",s[end].id); } } return 0; } int ok(long long x) { int u1=1,u2=n; int mid=0; while(u1<=u2) { mid=(u1+u2)/2; if(s[mid].data<x) { u1=mid+1; } else if(s[mid].data>x) { u2=mid-1; } else { return mid; } } return u2; }