E - 高橋君とホテル / Tak and Hotels
Time Limit: 3 sec / Memory Limit: 256 MB
Score : 700700 points
Problem Statement
NN hotels are located on a straight line. The coordinate of the ii-th hotel (1≤i≤N)(1≤i≤N) is xixi.
Tak the traveler has the following two personal principles:
- He never travels a distance of more than LL 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 QQ queries. The jj-th (1≤j≤Q)(1≤j≤Q) query is described by two distinct integers ajaj and bjbj. For each query, find the minimum number of days that Tak needs to travel from the ajaj-th hotel to the bjbj-th hotel following his principles. It is guaranteed that he can always travel from the ajaj-th hotel to the bjbj-th hotel, in any given input.
Constraints
- 2≤N≤1052≤N≤105
- 1≤L≤1091≤L≤109
- 1≤Q≤1051≤Q≤105
- 1≤xi<x2<...<xN≤1091≤xi<x2<...<xN≤109
- xi+1−xi≤Lxi+1−xi≤L
- 1≤aj,bj≤N1≤aj,bj≤N
- aj≠bjaj≠bj
- N,L,Q,xi,aj,bjN,L,Q,xi,aj,bj are integers.
Partial Score
- 200200 points will be awarded for passing the test set satisfying N≤103N≤103 and Q≤103Q≤103.
Input
The input is given from Standard Input in the following format:
NN x1x1 x2x2 ...... xNxN LL QQ a1a1 b1b1 a2a2 b2b2 : aQaQ bQbQ
Output
Print QQ lines. The jj-th line (1≤j≤Q)(1≤j≤Q) should contain the minimum number of days that Tak needs to travel from the ajaj-th hotel to the bjbj-th hotel.
Sample Input 1 Copy
Copy
9 1 3 6 13 15 18 19 29 31 10 4 1 8 7 3 6 7 8 5
Sample Output 1 Copy
Copy
4 2 1 2
For the 11-st query, he can travel from the 11-st hotel to the 88-th hotel in 44 days, as follows:
- Day 11: Travel from the 11-st hotel to the 22-nd hotel. The distance traveled is 22.
- Day 22: Travel from the 22-nd hotel to the 44-th hotel. The distance traveled is 1010.
- Day 33: Travel from the 44-th hotel to the 77-th hotel. The distance traveled is 66.
- Day 44: Travel from the 77-th hotel to the 88-th hotel. The distance traveled is 1010
让求x个点到y个点最少要走多少步,每次最多L步
刚开始写的模拟,也没写对,思路应该是倍增,fxy代表第x位置到2^y方次天最大能到达步数。先二分出fx0,用upper_bound函数即可。
然后转移状态fxy=f(fx(y-1))(y-1)。也就是第x位置的2^(y-1)次方步到 2^(y-1)天最大能到达步数。
然后从起点查询,若每一个状态<终点,那么ans+1,再转移现在的位置为f[x][i]。最后答案要加一。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=100006;
int a[maxn];
int f[maxn][36];
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
int l;
scanf("%d",&l);
int q;
scanf("%d",&q);
for(int i=1;i<=n;i++)
{
int id=(int)(upper_bound(a+1,a+n+1,a[i]+l)-a-1);
//找到最后一个一个比当前位置不大于L的位置
f[i][0]=id;//第i个位置走2的0次方次,也就是1次。
}
for(int j=1;j<=30;j++)
{
for(int i=1;i<=n;i++)
{
f[i][j]=f[f[i][j-1]][j-1];//---//转移状态,数组左边也就是前一步
}
}
while(q--)
{
int bx,by;
scanf("%d%d",&bx,&by);
if(bx>by)swap(bx,by);
int sum=0;
int x=bx;
for(int i=30;i>=0;i--)
{
if(f[x][i]<by)
{
sum+=(1<<i);
x=f[x][i];
}
}
printf("%d\n",sum+1);
}
return 0;
}
/*
9
1 3 6 13 15 18 19 29 31
10
6
1 2
1
1 4
*/