제출 #879849

#제출 시각아이디문제언어결과실행 시간메모리
879849HuyQuang_re_ZeroAliens (IOI16_aliens)C++14
100 / 100
293 ms15916 KiB
#include <bits/stdc++.h>
#define ll long long
#define db long double
#define II pair <ll,ll>
#define III pair <ll,II>
#define IV pair <vector <int>,vector <int> >
#define IDB pair <db,int>
#define TII pair <treap*,treap*>
#define fst first
#define snd second
#define BIT(x,i) ((x>>i)&1)
#define pi acos(-1)
#define to_radian(x) (x*pi/180.0)
#define to_degree(x) (x*180.0/pi)
#define Log(x) (31-__builtin_clz((int)x))
#define LogLL(x) (63-__builtin_clzll((ll)x))
using namespace std;
#include "aliens.h"
int flag;
db Pen;
struct ConvexHull_Trick
{
    struct Line { db a,b; int cnt; } st[100005];
    int top,j;
    void Init() { top=0; j=1; }
    db intersect(Line x,Line y)
    {
        return (y.b-x.b)/(x.a-y.a);
    }
    void add(db a,db b,int cnt)
    {
        while(top>1)
        {
            db y1=intersect({ a,b },st[top-1]),y2=intersect(st[top],st[top-1]);
            if(y1<y2 || (y1==y2 && st[top].cnt<cnt)) top--;
            else break;
        }
        if(top>0) j=min(j,top);
        else j=1;
        st[++top]={ a,b,cnt };
    }
    IDB get(db x)
    {
        while(j<top)
        {
            db y1=x*st[j].a+st[j].b,y2=x*st[j+1].a+st[j+1].b;
            if(y1>y2 || (y1==y2 && st[j].cnt<st[j+1].cnt)) j++;
            else break;
        }
        return { x*st[j].a+st[j].b,st[j].cnt };
    }
} CVH;


struct segment { ll l,r; } seg[100005];
int n,i,cnt[100005],del[100005];
db f[100005];
ll g[100005];
IDB cal(db pen)
{
    Pen=pen;
    CVH.Init();
    for(i=0;i<=n;i++)
    {
        if(i>0)
        {
            IDB k=CVH.get(seg[i].r);
            f[i]=k.fst+seg[i].r*seg[i].r+pen;
            cnt[i]=k.snd+1;
        }
        if(i<n)
        {
            g[i]=seg[i+1].l;
            CVH.add(-2*g[i],f[i]+g[i]*g[i]-max(0LL,seg[i].r-g[i])*max(0LL,seg[i].r-g[i]),cnt[i]);
        }
    }
    return { f[n],cnt[n] };
}
ll take_photos(int _n,int m,int k,vector <int> x,vector <int> y)
{
    n=_n;
    for(i=0;i<n;i++)
    {
        x[i]++; y[i]++;
        if(x[i]<=y[i]) seg[i+1]={ x[i]-1,y[i] };
        else seg[i+1]={ y[i]-1,x[i] };
    }
    sort(seg+1,seg+n+1,[&](segment a,segment b){ return a.l<b.l || (a.l==b.l && a.r>b.r); });
    priority_queue <II,vector <II>,greater <II> > h;
    for(i=n;i>=1;i--)
    {
        while(h.size()>0 && h.top().fst<=seg[i].r)
        {
            del[h.top().snd]=1;
            h.pop();
        }
        h.push({ seg[i].r,i });
    }

    vector <segment> tg;
    for(i=1;i<=n;i++)
        if(del[i]==0) tg.push_back(seg[i]);
    n=0;
    for(segment obj:tg) seg[++n]=obj;
    k=min(k,n);
    db l=0,r=1e15;
    while(r-l>1e-6)
    {
        db mid=(l+r)/2;
        if(cal(mid).snd>=k) l=mid; else r=mid;
    }
    flag=1;
    return round(cal(l).fst-k*l);
}

/*
int main()
{
    freopen("aliens.inp","r",stdin);
    freopen("aliens.out","w",stdout);
    int n,m,k,X,Y;
    cin>>n>>m>>k;
    vector <int> x,y;
    for(int i=1;i<=n;i++) cin>>X>>Y,x.push_back(X),y.push_back(Y);
    cout<<take_photos(n,m,k,x,y);
}
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...