加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

[Codeforces #514] Tutorial

发布时间:2020-12-14 04:19:53 所属栏目:大数据 来源:网络整理
导读:Link: Codeforces #514 传送门 很简单的一场比赛打崩了也是菜得令人无话可说…… D: 一眼二分,发现对于固定的半径和点,能包含该点的圆的圆心一定在一个区间内,求出区间判断即可 此题一个重要性质就是圆与$x$轴相切,画出圆心所在直线后就能想到上述贪心

Link:

Codeforces #514 传送门

很简单的一场比赛打崩了也是菜得令人无话可说……

D:

一眼二分,发现对于固定的半径和点,能包含该点的圆的圆心一定在一个区间内,求出区间判断即可

此题一个重要性质就是圆与$x$轴相切,画出圆心所在直线后就能想到上述贪心了

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<db,db> P;
const db eps=1e-7;
const int MAXN=1e5+10;
struct Data{db l,r;int id;}a[MAXN];
int n,cnt1,cnt2;P dat[MAXN];

bool cmp(Data a,Data b)
{return a.l<b.l;}
db sqr(db x){return 1.0*x*x;}
bool cal(db r,int k)
{
    db b=2*dat[k].X;
    db c=sqr(dat[k].X)+sqr(dat[k].Y-r)-sqr(r);
    if(sqr(b)-4*c<-eps) return false;
    a[k].id=k;
    a[k].l=(b-sqrt(sqr(b)-4*c))/2.0;
    a[k].r=(b+sqrt(sqr(b)-4*c))/2.0;
    return true;
}
bool check(db r)
{
    if(cnt1) r=-r;
    for(int i=1;i<=n;i++)
        if(!cal(r,i)) return false;
    db mn=1e60,mx=-1e60;
    for(int i=1;i<=n;i++)
        mn=min(mn,a[i].r),mx=max(mx,a[i].l);
    return mx<=mn;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&dat[i].X,&dat[i].Y);
        cnt1+=dat[i].Y<0;cnt2+=dat[i].Y>0;
    }
    if(n==1) return printf("%.6lf",dat[1].Y/2.0),0;
    if(cnt1&&cnt2) return puts("-1"),0;
    
    //实数二分最好直接枚举次数,否则精度可能不够 
    // 也可以相对误差和eps比较 
    db l=0,r=1e16;
    for(int i=1;i<=200;i++)
    {
        db mid=(l+r)/2.0;
        if(check(mid)) r=mid;
        else l=mid;
    }
    printf("%.6lf",l);
    return 0;
}
Problem D

做的时候先想的凸包,想到正解后把一个$int$开成$double$后调不出来……

所以发现输出全是整数时要敏感啊……

注意:实数二分不用$fabs(l-r)$,会爆精度,最好卡次数

E:

可以先预处理每个点向上走的最远距离在树上$dp$,

不过其实直接从低向上贪心走就好了,在之前被走过的点就不用走了

可以并查集维护也可以直接暴力走

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=2e5+10;
ll S,w[MAXN],pre[MAXN],res;
int n,L,f[MAXN],ufs[MAXN],vis[MAXN],dep[MAXN],out[MAXN];

int find(int x)
{return x==ufs[x]?x:find(ufs[x]);}
int main()
{
    scanf("%d%d%lld",&n,&L,&S);
    for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
    for(int i=2;i<=n;i++) 
        scanf("%d",&f[i]),out[f[i]]++;
    for(int i=1;i<=n;i++)
    {
        ufs[i]=i;
        if(w[i]>S) return puts("-1"),0;
    }
    for(int i=1;i<=n;i++)
        dep[i]=dep[f[i]]+1,pre[i]=pre[f[i]]+w[i];
    
    queue<int> q;
    for(int i=1;i<=n;i++)
        if(!out[i]) q.push(i);
    while(!q.empty())
    {
        int t=q.front();q.pop();
        if(vis[t]) continue;
        int cur=t;res++;
        int len=0;ll sum=0;
        while(len<=L&&sum<=S)
        {
            int nxt=find(cur);
            len+=dep[cur]-dep[nxt]+1;
            sum+=pre[cur]-pre[nxt]+w[nxt];
            if(len>L||sum>S) break;
            vis[nxt]=1;if(!f[nxt]) break;
            
            ufs[nxt]=find(f[nxt]);out[f[nxt]]--;
            if(!out[f[nxt]]&&!vis[f[nxt]]) q.push(f[nxt]);
            cur=f[nxt];
        }
    }
    printf("%lld",res);
    return 0;
}
Problem E

以后做完签到题后把所有题先看一遍再决定顺序!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读