码迷,mamicode.com
首页 > 其他好文 > 详细

蛤的旅行(倍增二进制拆分)

时间:2020-02-21 22:01:39      阅读:86      评论:0      收藏:0      [点我收藏+]

标签:ace   turn   控制   return   while   include   abs   关于   mat   

蛤的旅行
[题目描述]

长江的江心有n块石头。为了简化问题,我们把长江看做一条数轴,且所有石头的坐标均为正整数。

有一只蛤在这些石头上跳。这只蛤在长江中生活了数百年,多年与风浪搏斗的经验使他锻炼出了极强的跳跃能力,可以瞬间从一块石头跳到与其相距任意远的另一块石头上。

然而,在一次意外进入一片诡异的灌木林(bush)之后,这只蛤发现自己获得了一个自己无法控制的buff:改变天气。具体来说,蛤周围方圆数百里(足以覆盖所有石头)之内都会大雨滂沱,洪水泛滥,甚至连江心的石头都会因此而淹没。只有一块地方形成了一个异常的高压区,天气晴朗,石头也没有被淹没——巧合的是,没有被淹没的石头有且仅有一块,且恰好是距离蛤第m远的那块(如果有两块石头距离蛤一样远,则我们认为坐标较大的那块更远)。因此蛤很尴尬地发现自己只能跳到那块石头上了。

现在蛤想要知道:如果他一开始在第S块石头上,那么在跳了C次之后他会在哪块石头上?他给出了q次询问,要求你在1s内回答。

[输入格式]

第一行,两个正整数n,m,表示石头的数量,没有被淹没的石头距离自己第几远。

第二行,n个正整数X[i],表示石头的坐标。保证坐标单调递增。

第三行,一个正整数q,表示询问数。

接下来q行,每行两个正整数S,C,表示蛤一开始所在的石头以及跳的步数。

[输出格式]

对于每个询问输出一行,表示蛤最终所在的石头编号。

[输入样例]

6 3

1 6 8 10 11 15

6

1 3

2 4

3 4

4 3

5 2

6 3

[输出样例]

1

1

5

4

3

6

[数据范围]

对于40%的数据,2<=n<=1000,1<=q<=1000,1<=X[i]<=1e9,1<=C<=10000。

对于100%的数据,2<=n<=100000,1<=m<=n-1,1<=X[i]<=1e18,1<=q<=100000,1<=S<=n,1<=C<=100000。

题目描述很多坑:比如自己不算;第m(很容易写成第m近)。

然后就可以类似LCA的二进制拆分了。设st[i][j]表示从i开始跳\(2^j\)次的点的编号。于是只要知道所有的st[i][0]就可以知道所有的st[i][j],做到 \(O(\log n)\)查询。
关于st[i][0],考虑双指针,可以 \(O(n)\) 搞定。开始l=1,r=n-m+1.当dis(i,r+1)<dis(i,l)的时候说明最小的m个数可以更新,则++l,++r.每次st[i][0]取dis(i,l)和dis(i,r)较大的那个(l或r)。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=300000;
int st[N][19],ln=18;
int n,m,x[N],q;
int abss(int a)
{
    return a>0?a:-a;
}
int dis(int i,int j) {
    return abss(x[j]-x[i]);
}
signed main() {
    scanf("%lld%lld",&n,&m);
    for(int i=1; i<=n; ++i)scanf("%lld",&x[i]);
    int l=1,r=n-m+1;
    for(int i=1; i<=n; ++i) {
        while(dis(i,r+1)<dis(l,i))++l,++r;
        st[i][0]=dis(l,i)>=dis(i,r)?l:r;
    }
    for(int j=1; j<=ln; ++j)
        for(int i=1; i<=n; ++i)
            st[i][j]=st[st[i][j-1]][j-1];
    scanf("%lld",&q);
    int s,c;
    while(q--) {
        scanf("%lld%lld",&s,&c);
        for(int i=0;i<=ln;++i)
            if(c&(1<<i))s=st[s][i];
        printf("%lld\n",s);
    }
    return 0;
}

蛤的旅行(倍增二进制拆分)

标签:ace   turn   控制   return   while   include   abs   关于   mat   

原文地址:https://www.cnblogs.com/zzctommy/p/12343193.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!