lj的锁

lj的锁

Lj花很大力气设计了一个锁,有一天,lj用这个锁把lbn锁在了一个小房间里,准备把lbn啊掉,现在lbn要逃出这个房间,他需要解开这个锁。在平面上有n个钉子,第i个钉子的位置是(x[i],0),你需要回答m个问题,每个问题都是如下格式的:如果在第a[i]个钉子上挂一条长为l[i],末端有一个重锤的轻绳,并让它沿逆时针方向做圆周运动,显然由于大量钉子的存在,绳子会绕在一些钉子上并最终围绕其中一个钉子做圆周运动,求最后绳子做圆周运动的圆心是哪颗钉子。然而lj还有2s就要抓到lbn了,lbn为了逃命不得不求助于你,让你帮他解决那些数不清的询问。第一行两个整数n,m(1<=n,m<=2*10^5),代表钉子的个数和询问的个数。第二行n个整数x[1],x[2],…,xn,代表钉子的横坐标,保证坐标各不相同。接下来m行,每行两个整数a[i],li,代表一个询问中绳子最初挂在的钉子编号以及绳子的长度

这道题二分即可。。二分真是奥妙重重。

#include <cctype>
#include <cstdio>
#include <algorithm>
using namespace std;
 
typedef long long LL;
const LL maxn=2e5+5;
LL n, m;
struct node{
    LL data, id;
}ar[maxn];
LL wentto[maxn], where[maxn], x[maxn], maxl, minr;
bool operator <(const node a, const node b){
    return a.data<b.data;
}
 
inline LL getLL() {
    register char ch;
    register bool neg=false;
    while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
    register LL x=ch^'0';
    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    return neg?-x:x;
}
 
int main(){
    scanf("%lld%lld", &n, &m);
    for (LL i=0; i<n; ++i){
        ar[i].data=getLL();
        ar[i].id=i;
    }
    sort(ar, ar+n);
    for (LL i=0; i<n; ++i){
        wentto[ar[i].id]=i;
        where[i]=ar[i].id;
        x[i]=ar[i].data;
    }
    LL a, lpos, rpos, dis;
    LL l;
    for (LL i=0; i<m; ++i){
        a=getLL(), l=getLL();
        a=wentto[a-1];
        //lrpos存下标.lpos查大于等于它的,rpos小于等于它的
        maxl=0, minr=n;
        rpos=lower_bound(x, x+n, l+x[a])-x;
        if (rpos+1<minr) minr=rpos+1;
        if (x[rpos]!=l+x[a]) --rpos;
        lpos=lower_bound(x, x+n, x[a]-l)-x;
        while (lpos<rpos){
            l-=x[rpos]-x[a];
            a=rpos;
            lpos=lower_bound(x+maxl, x+minr, x[a]-l)-x;
            if (lpos>maxl) maxl=lpos;
            l-=x[a]-x[lpos];
            a=lpos;
            rpos=lower_bound(x+maxl, x+minr, l+x[a])-x;
            if (x[rpos]!=l+x[a]) --rpos;
            dis=x[rpos]-x[lpos];
            if (dis) l=l%(dis*2);
            rpos=lower_bound(x+maxl, x+minr, l+x[a])-x;
            if (x[rpos]!=l+x[a]) --rpos;
            if (rpos+1<minr) minr=rpos+1;
        }
        printf("%lld\n", where[a]+1);
    }
    return 0;
}
posted @ 2017-09-27 10:41  pechpo  阅读(317)  评论(0编辑  收藏  举报