题目
题意
有一个点在第1分钟位于
a
a
a这个位置
从第2~
n
n
n分钟可以向上或向下走最多
d
d
d的高度
要求在第
n
n
n分钟结束后到达
b
b
b这个位置,求能到达的最高高度
分析
先考虑
O
(
n
)
O(n)
O(n)
设当前高度为
x
x
x
很显然对于一个
i
(
2
≤
i
≤
n
)
i(2≤i≤n)
i(2≤i≤n),如果是合法的,满足
x
+
d
−
d
∗
(
n
−
i
)
≤
b
x+d-d*(n-i)≤b
x+d−d∗(n−i)≤b
如果成立,答案和
x
+
d
x+d
x+d取
m
a
x
max
max
如果不成立,那么最高高度只能是
b
+
d
∗
(
n
−
i
)
b+d*(n-i)
b+d∗(n−i),和答案取
m
a
x
max
max
但是看到
n
n
n是小于等于1012的,
O
(
n
)
O(n)
O(n)是过不去的,考虑优化
我们可以二分求出最大的
i
i
i使得
a
+
d
∗
(
i
−
1
)
−
d
∗
(
n
−
i
)
≤
b
a+d*(i-1)-d*(n-i)≤b
a+d∗(i−1)−d∗(n−i)≤b成立,这样的话时间就是
O
(
l
o
g
(
n
)
)
O(log(n))
O(log(n))
Code
#include<cstdio>
#include<iostream>
using namespace std;
long long i,n,d,a,b,l,r,mid,ans;
int main()
{
freopen("mountain.in","r",stdin);
freopen("mountain.out","w",stdout);
scanf("%lld%lld%lld%lld",&n,&d,&a,&b);
l=2;
r=n;
while (l<=r)
{
mid=(l+r)>>1;
if (a+d*(mid-1)-d*(n-mid)<=b)
{
l=mid+1;
ans=max(ans,a+d*(mid-1));
}
else
{
r=mid-1;
ans=max(ans,b+d*(n-mid));
}
}
printf("%lld\n",ans);
fclose(stdin);
fclose(stdout);
return 0;
}