• 独木桥(bridge)


    独木桥(bridge)

    题目描述

     

    Alice和Bob是好朋友,这天他们带了n个孩子一起走独木桥。

    独木桥宽度很窄,不允许两个或两个以上的人并肩行走,所有人必须要前后一个接一个地通行。

    Bob给所有的孩子蒙上了眼,并将他们放在桥中不同的位置上,孩子们初始的朝向不一定相同。Bob吹响哨声后这些孩子们会按照初始的朝向开始移动,当两个孩子移动到同一点时由于桥太窄他们无法穿过彼此,因此他们会同时转身改变朝向,并接着朝新方向移动。

    为了安全起见,在某个时刻Alice会询问Bob某个孩子现在所处的位置。

    更具体的,我们可以将问题抽象如下:

    · 将独木桥看作一个长度无限长的实数轴,将每个孩子看作数轴上的一个实数点。数轴从左到右坐标不断增大。

    · 孩子的位置用相对于数轴原点的点的坐标来表示。初始时n个点在n个互不相同的整点上。

    · 每个点有一个初始朝向(从左向右或从右向左)。任何时刻所有的点都会以每秒1单位长度的速度匀速向所朝的方向移动。当某个时刻两个点同时移动到了同一个位置上,它们会立即改变自己的朝向(从左向右变成从右向左,反之亦然),然后继续移动。

    ·有qq次询问,每次询问给定kiki与titi,询问在titi秒后,孩子kiki目前的位置。

    Bob无法同时关注这么多的孩子,请你帮帮他。

     

     

    输入

     

    第一行一个整数nn表示孩子数,孩子从00开始编号。

    第二行nn个整数pipi,表示孩子们的初始位置。

    第三行nn个整数didi,表示孩子们的初始朝向。di=0di=0则初始向左,di=1di=1则初始向右。

    第四行一个整数qq 表示询问数。

    接下来qq行每行两个整数ki,tiki,ti表示一个询问,询问在titi秒

    后,孩子kiki (按输入顺序)目前的位置。


    【数据范围】

    20%的数据:n,pi,ti≤10n,pi,ti≤10

    另有20%的数据:di均相同

    另有20%的数据:q≤10q≤10

    另有15%的数据:ti≤100ti≤100

    另有15%的数据:n≤1000n≤1000

    1OO%的数据:1≤n,q≤2∗1051≤n,q≤2∗105, 0≤ki<n0≤ki<n, 0≤pi,ti≤1090≤pi,ti≤109,di∈0,1di∈0,1

     


    solution

    首先可以发现,各个蚂蚁之间的相对位置不变

    也就是说,如果k开始时排在rk_k.那么询问是也是询问rk_k的位置

    我很弱只会暴力排序的做法 

    可以二分答案,然后再对朝左的和朝右的分别二分个数

    小绿O(nlog^2n)

    orzboen 2.5k分讨实现O(nlogn)

    orzjarden 2.5k线段树上分讨实现O(nlogn)

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define maxn 200005
    #define inf 2e9
    #define ll long long
    using namespace std;
    int n,rk,t,dy[maxn],t1,t2;
    struct node{
        int pl,d,id;
    }s[maxn],a[maxn],b[maxn];
    int pd(ll k){
        int l=0,r=t1,sum=0;
        while(l<r){
            int mid=l+r+1>>1;
            if(a[mid].pl-t<=k)l=mid;
            else r=mid-1;
        }
        sum=sum+l;
        l=0,r=t2;
        while(l<r){
            int mid=l+r+1>>1;
            if(b[mid].pl+t<=k)l=mid;
            else r=mid-1;
        }
        sum=sum+l;
        //cout<<k<<' '<<sum<<endl;
        return sum;
    }
    bool cmp(node a,node b){
        return a.pl<b.pl;
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%d",&s[i].pl);
            s[i].id=i;
        }
        for(int i=1;i<=n;i++)scanf("%d",&s[i].d);
        sort(s+1,s+n+1,cmp);
        for(int i=1;i<=n;i++){
            dy[s[i].id]=i;
            if(s[i].d==0)a[++t1]=s[i];
            else b[++t2]=s[i];
        }
        int Q;cin>>Q;
        for(int i=1;i<=Q;i++){
            scanf("%d%d",&rk,&t);rk++;
            rk=dy[rk];
            ll l=-inf,r=inf;
            while(l<r){
                ll mid=l+r>>1;
                if(pd(mid)<rk)l=mid+1;
                else r=mid;
            }
            printf("%lld
    ",l);
        }
        return 0;   
    }
  • 相关阅读:
    Oracle Instance
    第03章-VTK系统概述(1)
    二叉查找树BST----java实现
    [Golang] 从零開始写Socket Server(2): 自己定义通讯协议
    linux之SQL语句简明教程---LIKE
    spring mvc 入门示例
    MyBatis与Spring集成
    MyBatis 一对一关联查询
    MyBatis CRUD Java POJO操作
    eclipse xml自动提示
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358783.html
Copyright © 2020-2023  润新知