【题解】Codeforces Round #573 (Div. 1) E. Tokitsukaze and Explosion
作者:互联网
其实官方题解已经非常清晰了。
主要是记录一下自己犯的错误。
最近要好好搞搞计算几何!
- 直接用角度区间判,并且还不用eps。可能1e5的坐标,acos,atan2之类的精读还行?
- 扩展成2 * n个时一定要保证右端点最大 - 最小 <= 2 * pi , 因为后面贪心是对右端点做得,所以不用考虑左端点。这样可以保证扩展后右端点还是递增的!
3. 这个倍增的思路还是挺常见的。直接贪心做不了,用倍增加速求答案!
#include<bits/stdc++.h>
using namespace std;
typedef double ld;
const int maxn = 2e5 + 10;
const ld pi = acos(-1.0);
const ld inf = 1e12;
const ld eps = 1e-9;
struct node{
ld l,r;
bool operator < (node a)const{
return r < a.r;
}
node operator + (ld a){
return (node){l + a,r + a};
}
}dt[maxn];
int f[maxn][20],n,m;
ld ang[maxn],X[maxn],Y[maxn],dis[maxn];
int tag;
bool check(ld mid){
for (int i = 1 ; i <= n ; i++){
ld t = acos(mid / dis[i]);
dt[i] = (node){ang[i] - t,ang[i] + t};
if ( dt[i].r > pi ) dt[i] = dt[i] + (-2 * pi); //只需要使得右端点差距不超过2 * pi即可,不用管左端点
}
sort(dt + 1,dt + n + 1);
for (int i = 1 ; i <= n ; i++) dt[i + n] = dt[i] + 2 * pi;
int N = 2 * n;
for (int i = 1 ; i <= N ; i++){
int cur = min(N,max(f[i - 1][0],i + 1));
while ( cur < min(N,i + n) && dt[cur].l <= dt[i].r ) cur++;
f[i][0] = cur;
if ( tag ) cout<<i<<" "<<f[i][0]<<endl;
}
if ( tag ) for (int i = 1 ; i <= N ; i++) cout<<i<<" "<<dt[i].l<<" "<<dt[i].r<<endl;
for (int j = 1 ; j < 20 ; j++) for (int i = 1 ; i <= N ; i++){
f[i][j] = f[f[i][j - 1]][j - 1];
}
for (int i = 1 ; i <= n ; i++){
int cur = 0 , id = i;
for (int j = 19 ; j >= 0 ; j--){
if ( f[id][j] < i + n ){
cur += 1 << j;
id = f[id][j];
}
}
cur++;
if ( tag) cout<<i<<" "<<cur<<endl;
if ( cur <= m ) return 1;
}
return 0;
}
int main(){
scanf("%d %d",&n,&m);
cout<<setprecision(10);
ld l = 0 , r = inf;
for (int i = 1 ; i <= n ; i++){
int x,y;
scanf("%d %d",&x,&y);
X[i] = x , Y[i] = y;
dis[i] = sqrt(X[i] * X[i] + Y[i] * Y[i]) , r = min(r,dis[i]) , ang[i] = atan2(Y[i],X[i]);
}
while ( (r - l) > eps ){
ld mid = (l + r) / 2;
if ( !check(mid) ) r = mid;
else l = mid;
}
// cout<<l<<" "<<r<<endl;
//printf("%.10lf\n",r);
cout<<r<<endl;
}
标签:ld,Explosion,573,题解,mid,int,maxn,const,dt 来源: https://blog.csdn.net/weixin_42484877/article/details/98474207