Description
有n个人站在数轴上,第i个人在Xi
每个人手上都有一个能燃烧T秒的烟花,刚开始时只有编号为k的人手上的烟花是燃着的
只允许用燃着的烟花去点燃未点燃的烟花,当且仅当两个人的位置重叠且一个人手上的烟花点燃时能点燃另一个人的烟花
问将所有人手上的烟花都点燃的过程中,所有人瞬时速度的最大值最小可以是多少
n<=10^5
Solution
考虑二分答案v,对于区间[i,j],最后一个人可能在的坐标区间是[xj-vT(j-i),xi+vT(j-i)],如果满足xj-vT(j-i)<=xi+vT(j-i)则合法
令ai=xi-2vTi,那么条件转化为ai>=aj则区间[i,j]合法
现在问题变成了,刚开始在[k,k],每次可以往左或往右扩展一步,需要时刻保证区间合法,问能否走到[1,n]
考虑贪心,设当前在区间[x,y],如果存在i<x满足min(ai~ax)>=ay且ai>ax走过去显然不劣
右边同理,我们可以预处理出每个点左边第一个>a[x]和右边第一个<a[y]的点
然后用st表维护区间最值
如果不能走了的话只能暴力往两边走,注意中途不能跨过不合法的区间
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
int read() {
char ch;
for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
int x=ch-'0';
for(ch=getchar();ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x;
}
const int N=1e5+5;
const ll inf=1e18;
int n,T,k,f[N][17],g[N][17],x[N],lg[N],sta[N],L[N],R[N],top;
ll b[N];
int get_mn(int l,int r)