题解:区间[L,R]得出的答案我们知道,它最多有一个端点的线段会被截断。故二分的时候固定一个线段的端点就好了。然后枚举最右端的那条线段是否被分隔开。 然后固定右端点,分割左端点的线段。
#include<bits/stdc++.h>
#define fuck(x) cout<<'['<<#x<<' '<<x<<']'<<endl
using namespace std;
const double eps = 1e-8;
typedef long long ll;
const int MX = 2e5+7;
double cnt[MX],sum[MX],x[MX],y[MX];
int n,tail;
double L,R,ans;
int dcmp(double a)
{
if(fabs(a) < eps) return 0;
return a < 0? -1 : 1;
}
double check(int id, double mid)
{
int k = lower_bound(cnt,cnt+tail,mid) - cnt;
k = min(tail-1,k);
double ret = sum[k] - sum[id];
if(k&1) ret -= max(0.0, cnt[k]-mid); //线段是1-0,3-2,5-4这样的,所以必须是奇数才能减
return ret;
}
void update(int id, double mid, bool rev)
{
double l,r;
if(rev){
r = x[n] - cnt[id];
l = x[n] - mid;
}
else{
l = cnt[id];
r = mid;
}
if(dcmp(r-l-ans) <= 0){
ans = r-l;
L = l;
R = r;
}
}
void work(bool rev,double A)
{
for(int i = 0; i < tail; i += 2){
double l = cnt[i], r = x[n]+1;
for(int j = 1; j <= 60; j++){
double mid = (l+r)*0.5;
if(dcmp(check(i,mid)-A ) >= 0) r = mid;
else l = mid;
}
if(l > x[n]+0.1) break;
update(i,l,rev);
}
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
#else
freopen("bayes.in", "r", stdin);
freopen("bayes.out", "w", stdout);
#endif // LOCAL
double a,b,A;
while(~scanf("%d",&n)){
if(n == 0) break;
tail = 0;
scanf("%lf%lf%lf",&a,&b,&A);
for(int i = 0; i <= n; i++){
scanf("%lf%lf",&x[i],&y[i]);
}
for(int i = 1; i <= n; i++){
double dx = x[i] - x[i-1], dy = y[i] - y[i-1];
if(dcmp(dy) == 0 && a <= y[i] && y[i] <= b){
cnt[tail++] = x[i-1];
cnt[tail++] = x[i];
}
else{
double t = dy/dx;
double xl = x[i-1] + (t < 0? (b-y[i-1])/t : (a-y[i-1])/t);
double xr = x[i] + (t < 0? (a-y[i])/t : (b-y[i])/t );
xl = max(xl,x[i-1]);
xr = min(xr,x[i]);
if(xl > xr) continue;
cnt[tail++] = xl;
cnt[tail++] = xr;
}
}
double len = 0;
for(int i = 1; i < tail; i+=2){
len += cnt[i] - cnt[i-1];
}
A *= len;
ans = x[n]; L = 0, R = 0;
for(int i = 1; i < tail; i++){
if(i&1) sum[i] = sum[i-1] + cnt[i] - cnt[i-1];
else sum[i] = sum[i-1];
}
work(0,A);
for(int i = 0; i < tail; i++)
cnt[i] = x[n] - cnt[i];
reverse(cnt,cnt+tail);
for(int i = 1; i < tail; i++){
if(i&1) sum[i] = sum[i-1] + cnt[i] - cnt[i-1];
else sum[i] = sum[i-1];
}
work(1,A);
printf("%.12f %.12f\n",L,R);
}
return 0;
}