傳送門biu~
對於一個氣球i,如果它左邊的某個氣球j的右邊有比j大的氣球,顯然j不會對i的大小產生影響。所以能夠影響氣球i的大小的氣球集合是座標遞增半徑遞減的。
我們把這些氣球放在一個棧裏,從棧頂的氣球開始考慮其對第i個氣球的影響。第i個氣球的半徑初始化爲上限ri,然後用棧頂的氣球更新半徑。
如果更新後第i個氣球的半徑比棧頂氣球半徑大,那麼這個棧頂之後就沒有用了,彈棧。如果此時棧非空,那麼繼續考慮新的棧頂對第i個氣球的影響。
如果更新後第i個氣球的半徑比棧頂氣球半徑小,考慮在棧頂氣球的左側的氣球。既然棧頂的氣球在第i個氣球的左側且現在半徑比第i個氣球大,那麼棧頂氣球左側的氣球顯然就不能碰到第i個氣球。
此時棧裏的其它氣球不再對第i個氣球的大小產生影響。我們此時得到了第i個氣球的最終答案,把第i個氣球扔到棧裏就可以繼續考慮第i+1個氣球了。
#include<bits/stdc++.h>
#define N 200005
using namespace std;
int n,q[N],top;
double x[N],r[N];
inline double Cut(int i,int j){return (x[i]-x[j])*(x[i]-x[j])/(4*r[i]);}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%lf%lf",&x[i],&r[i]);
while(top){
r[i]=min(r[i],Cut(q[top],i));
if(r[q[top]]<r[i]) --top;
else break;
}
q[++top]=i;
printf("%.3lf\n",r[i]);
}
return 0;
}