平面上有n個釘子,他們從1到n編號,第i個釘子的座標是 (xi, 0)。然後我們我們把一個長度爲L,帶重物的繩子繫到第i個釘子上(那麼重物所在的座標是(xi, -L))。然後用力將重物向右推,開始逆時針旋轉。同時,如果旋轉的過程中碰到其它的釘子,就會繞着那個釘子旋轉。假設每個釘子都很細,重物繞着它旋轉時,不影響到繩子的長度。
更一般的,如果繩子碰到多個釘子,那麼它會繞着最遠的那個釘子轉。特殊的,如果繩子的末端碰到了一個釘子,那麼也會繞着那個釘子以長度爲0的繩子在轉。
經過一段時間之後,重物就會一直繞着某個釘子轉。
現在有m個查詢,每個查詢給出初始的繩子長度以及掛在哪個釘子下旋轉,請找出重物最終會繞哪個釘子旋轉。
樣例解釋:
單組測試數據。 第一行包含兩個整數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。
輸出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; }