Codeforces Round #514 (Div. 2) D. Nature Reserve

时间:2023-01-21 17:38:36

http://codeforces.com/contest/1059/problem/D

最大值:

最左下方和最右下方分别有一个点

r^2 - (r-1)^2 = (10^7)^2

maxr<0.5*10^14

Way1:

二分。

difference:

如果使用 5*10^13 -> 10^-6,2^ 60~70区间,pow,sqrt运算,实测超时。

实际上是Codeforces Round #514 (Div. 2) D. Nature Reserve,使用Codeforces Round #514 (Div. 2) D. Nature Reserve

time of a case:Codeforces Round #514 (Div. 2) D. Nature Reserve->Codeforces Round #514 (Div. 2) D. Nature Reserve

Code:

 #include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+; double x[maxn],y[maxn];
double z=5.0*1e13;
int n; bool work(double m)
{
double p,q,d;
int i;
p=-z; q=z;
for (i=;i<=n;i++)
{
d=sqrt(pow(m,)-pow(m-y[i],));
p=max(p,x[i]-d);
q=min(q,x[i]+d);
// if (p>q)
// return 0;
}
// return 1;
if (p<=q)
return ;
else
return ;
} int main()
{
double l=,r,m;
int v,i;
scanf("%d",&n);
v=;
for (i=;i<=n;i++)
{
scanf("%lf%lf",&x[i],&y[i]);
if (y[i]!=)
{
if (v==)
v=(y[i]>);
else if (v!=(y[i]>))
{
printf("-1");
return ;
}
}
y[i]=fabs(y[i]);
l=max(l,y[i]/);
}
r=z;
while ((r-l)/max(1.0,l)>1e-)
{
m=(l+r)/;
if (work(m))
r=m;
else
l=m;
}
printf("%.10f",r);
return ;
}

Way2:

多个二次函数f1,f2,…,fn,ax^2+bx+c (a>0)

f(x)=max(f1(x),f2(x),…,fn(x)),

而f是先减小,后增大,使用三分法

证明:

设f(x)是由多个连续的二次函数片段组成,相邻的二次函数片段的斜率逐渐增大,而每个二次函数片段都是f''>0,所以当前f''>0

Codeforces Round #514 (Div. 2) D. Nature Reserve

设加入新的函数后,变化的区间为

1.[d1,d2],新的函数的片段替代原来的部分,满足f'‘’>0,且新的函数的片段往d1外,点外延伸,比原来的数值小,满足f'(d1-delta)<f'(d1+delta),f'(d2-delta)<f'(d2+delta)

2.(-inf,d1],[d1,inf)同理。

 #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define minv 1e-6
#define inf 1e9
#define pi 3.1415926536
#define nl 2.7182818284
const ll mod=1e9+;//
const int maxn=1e5+; int a[maxn],b[maxn],x[maxn],y[maxn],n;
double u[maxn],v[maxn],w[maxn]; double f(double m)
{
double mm,z=;
int i;
mm=m*m;
for (i=;i<=n;i++)
z=max(z,u[i]*mm+v[i]*m+w[i]);
return z;
} int main()
{
int cond=,i;
double l,r,m,mm,a,b;
scanf("%d",&n);
for (i=;i<=n;i++)
{
scanf("%d%d",&x[i],&y[i]);
if (y[i]!=)
{
if (cond==)
cond=(y[i]>);
else if (cond!=(y[i]>))
{
printf("-1");
return ;
}
}
y[i]=abs(y[i]);
u[i]=0.5/y[i];
v[i]=-1.0*x[i]/y[i];
w[i]=(1.0*x[i]*x[i]+1.0*y[i]*y[i])//y[i];
}
l=-1.0e7,r=1.0e7;
while ()
{
m=(l+r)/;
mm=(m+r)/;
a=f(m);
b=f(mm);
if (fabs(a-b)/max(1.0,min(a,b))<1e-)
break;
if (f(mm)>f(m))
r=mm;
else
l=m;
}
printf("%.10f",a);
return ;
}

Codeforces Round #514 (Div. 2) D. Nature Reserve

类似:

hdu4717 The Moving Points