在题目中:
为了简化问题,我们假设移动公司,所有的基站、up 主家位于同一条直线上,他们都位于这一条直线上的某一点 x,这些点不会重合。每个基站发射和接收的范围都是一个切于地面的圆,发射的半径 r 是固定的,接收半径 r′ 是可调的的。如下图:
但是我发现在数据中出现了重合的点
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
int n;
ll m;
struct Node{
ll id,pos,r,v;
ld f,x,y,k,a;
Node(){
id=pos=r=v=x=y=k=a=0;
f=1e308;
}
};
Node t[500001];
auto getk(int i,int j)->ld{return t[i].x==t[j].x?(t[i].y<t[j].y?1e308:-1e308):(t[i].y-t[j].y)/(t[i].x-t[j].x);};
bool cmp(int i,int j,int k){
return (t[i].y-t[j].y)*(t[j].x-t[k].x)>(t[j].y-t[k].y)*(t[i].x-t[j].x);
}
void cdq(int l,int r){
if (l==r){
t[l].x=t[l].a;
t[l].y=t[l].f-t[l].pos*t[l].a;
return;
}
int mid=(l+r)>>1;
cdq(l,mid);
sort(t+mid+1,t+r+1,[](Node u,Node v){return u.k<v.k;});
deque<int> q;
for (int i=l;i<=mid;i++){
while (q.size()>1 and cmp(q.at(q.size()-2),q.back(),i)) q.pop_back();
q.push_back(i);
}
for (int i=mid+1;i<=r;i++){
while (q.size()>1 and getk(q.at(0),q.at(1))<t[i].k) q.pop_front();
int j=q.at(0);
t[i].f=min(t[i].f,t[j].f+(t[i].pos-t[j].pos)*t[j].a+t[i].v);
}
sort(t+mid+1,t+r+1,[](Node u,Node v){return u.id<v.id;});
cdq(mid+1,r);
sort(t+l,t+r+1,[](Node u,Node v){return u.x<v.x;});
}
int main(){
cin.tie(0)->sync_with_stdio(false);
cout.tie(0);
cin>>n>>m;
for (int i=1;i<=n;i++){
cin>>t[i].pos>>t[i].r>>t[i].v;
}
for (int i=1;i<n;i++){
if (t[i].pos==t[i+1].pos){
cout<<"Genshin Impact Start!";
return 0;
}
}
// sort(t+1,t+n+1,[](Node u,Node v){return u.pos<v.pos;});
for (int i=1;i<=n;i++){
t[i].a=0.5/sqrtl(t[i].r);
t[i].k=-t[i].pos;
t[i].id=i;
}
t[1].f=t[1].v;
cdq(1,n);
sort(t+1,t+n+1,[](Node u,Node v){return u.id<v.id;});
ld minn=1e308;
for (int i=1;i<=n;i++){
// cout<<t[i].f<<" ";
if (t[i].pos-t[i].r<=m and m<=t[i].pos+t[i].r){
minn=min(minn,t[i].f);
}
}
cout<<fixed<<setprecision(3)<<minn;
return 0;
}