高橋君とホテル / Tak and Hotels

Posted mxzf0213

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高橋君とホテル / Tak and Hotels相关的知识,希望对你有一定的参考价值。

高橋君とホテル / Tak and Hotels


Time limit : 3sec / Stack limit : 256MB / Memory limit : 256MB

Score : 700 points

Problem Statement

N hotels are located on a straight line. The coordinate of the i-th hotel (1≤iN) is xi.

Tak the traveler has the following two personal principles:

  • He never travels a distance of more than L in a single day.
  • He never sleeps in the open. That is, he must stay at a hotel at the end of a day.

You are given Q queries. The j-th (1≤jQ) query is described by two distinct integers aj and bj. For each query, find the minimum number of days that Tak needs to travel from the aj-th hotel to the bj-th hotel following his principles. It is guaranteed that he can always travel from the aj-th hotel to the bj-th hotel, in any given input.

Constraints

  • 2≤N≤105
  • 1≤L≤109
  • 1≤Q≤105
  • 1≤xi<x2<…<xN≤109
  • xi+1−xiL
  • 1≤aj,bjN
  • ajbj
  • N, L, Q, xi, aj, bj are integers.

Partial Score

  • 200 points will be awarded for passing the test set satisfying N≤103 and Q≤103.

Input

The input is given from Standard Input in the following format:

N
x1 x2  xN
L
Q
a1 b1
a2 b2
:
aQ bQ

Output

Print Q lines. The j-th line (1≤jQ) should contain the minimum number of days that Tak needs to travel from the aj-th hotel to the bj-th hotel.


Sample Input 1

9
1 3 6 13 15 18 19 29 31
10
4
1 8
7 3
6 7
8 5

Sample Output 1

4
2
1
2

For the 1-st query, he can travel from the 1-st hotel to the 8-th hotel in 4 days, as follows:

  • Day 1: Travel from the 1-st hotel to the 2-nd hotel. The distance traveled is 2.
  • Day 2: Travel from the 2-nd hotel to the 4-th hotel. The distance traveled is 10.
  • Day 3: Travel from the 4-th hotel to the 7-th hotel. The distance traveled is 6.
  • Day 4: Travel from the 7-th hotel to the 8-th hotel. The distance traveled is 10.

分析:对于每个点二分可以找到一天所能到达的最右和最左端点;

   然后关键就是倍增,这样每个小问题就可以在log复杂度解决了;

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000000
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=1e5+10;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
int n,m,k,t,l[30][maxn],r[30][maxn];
ll a[maxn],p;
void init()
{
    memset(l,-1,sizeof l);
    memset(r,-1,sizeof r);
    for(int i=0;i<=n-1;i++)
    {
        r[0][i]=lower_bound(a,a+n,a[i]+p)-a;
        if(r[0][i]==n||a[r[0][i]]>a[i]+p)r[0][i]--;
        l[0][i]=lower_bound(a,a+n,a[i]-p)-a;
        if(i==n-1)r[0][i]=-1;
        if(i==0)l[0][i]=-1;
    }
    for(int i=1;i<=29;i++)
    {
        for(int j=0;j<=n-1;j++)
        {
            if(r[i-1][j]<n-1)r[i][j]=r[i-1][r[i-1][j]];
            if(l[i-1][j]>0)l[i][j]=l[i-1][l[i-1][j]];
        }
    }
}
int main()
{
    int i,j;
    scanf("%d",&n);
    rep(i,0,n-1)scanf("%lld",&a[i]);
    scanf("%lld",&p);
    init();
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int b,c,ans=0;
        scanf("%d%d",&b,&c);
        b--,c--;
        if(b<c)
        {
            for(i=29;i>=0;i--)
            {
                if(r[i][b]!=-1&&r[i][b]<=c)
                {
                    ans+=qpow(2,i);
                    b=r[i][b];
                    if(b==c)break;
                }
            }
            if(i==-1)ans++;
        }
        else
        {
            for(i=29;i>=0;i--)
            {
                if(l[i][b]!=-1&&l[i][b]>=c)
                {
                    ans+=qpow(2,i);
                    b=l[i][b];
                    if(b==c)break;
                }
            }
            if(i==-1)ans++;
        }
        printf("%d\n",ans);
    }
    //system("Pause");
    return 0;
}

以上是关于高橋君とホテル / Tak and Hotels的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Tak and Hotels

scss 木村さん_ホテルオリエンタル心斎桥アニメーション

AtCoder-arc060 (题解)

1801日語听解4第2回:3月2日

[动态规划]Tak and Cards

scss 161007ホワっとホバーしたり色々