제출 #309815

#제출 시각아이디문제언어결과실행 시간메모리
309815phathnvAliens (IOI16_aliens)C++11
100 / 100
189 ms8720 KiB
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

struct segment{
    int l, r;
    segment(int _l, int _r){
        l = _l;
        r = _r;
    }
};

struct line{
    ll a, b;
    int cnt;
    line(ll _a = 0, ll _b = 0, int _cnt = 0){
        a = _a;
        b = _b;
        cnt = _cnt;
    }
};

struct convexHull{
    vector <line> d;
    int ptr;
    void reset(){
        d.clear();
        ptr = 0;
    }
    ll calcY(const line &l, ll x){
        return l.a * x + l.b;
    }
    bool bad(const line &l1, const line &l2, const line &l3){
        return (l2.a - l3.a) * (l2.b - l1.b) >= (l1.a - l2.a) * (l3.b - l2.b);
    }
    void add(const line &newLine){
        while (d.size() > 1){
            if (bad(d[d.size() - 2], d[d.size() - 1], newLine))
                d.pop_back();
            else
                break;
        }
        d.push_back(newLine);
    }
    ll getMin(ll x){
        assert(!d.empty());
        ptr = min(ptr, (int) d.size() - 1);
        while (ptr < (int) d.size() - 1)
            if (calcY(d[ptr], x) >= calcY(d[ptr + 1], x))
                ptr++;
            else
                break;
        return calcY(d[ptr], x);
    }
    int getCnt(ll x){
        assert(!d.empty());
        ptr = min(ptr, (int) d.size() - 1);
        while (ptr < (int) d.size() - 1)
            if (calcY(d[ptr], x) >= calcY(d[ptr + 1], x))
                ptr++;
            else
                break;
        return d[ptr].cnt;
    }
} cvh;

int n, m, k;
vector <segment> segs;
vector <vector <ll> > dp;

void prepare(){
    sort(segs.begin(), segs.end(), [](const segment &a, const segment &b){
        if (a.l != b.l)
            return a.l < b.l;
        return a.r > b.r;
    });

    vector <segment> tmp;
    int maxR = -1;
    for(segment s : segs){
        if (s.r > maxR)
            tmp.push_back(s);
        maxR = max(maxR, s.r);
    }
    segs = tmp;
    n = segs.size();
}

ll cost(int l, int r){
    assert(l <= r || l > 0);
    int w = segs[r].r - segs[l].l + 1;
    int intersect = max(0, segs[l - 1].r - segs[l].l + 1);
    return (ll) w * w - (ll) intersect * intersect;
}

ll calc(ll c, bool value = 0){
    cvh.reset();

    cvh.add(line(-2 * segs[1].l, (ll) segs[1].l * segs[1].l, 0));
    ll val, cnt;
    for(int i = 1; i <= n; i++){
        val = cvh.getMin(segs[i].r + 1) + (ll) (segs[i].r + 1) * (segs[i].r + 1) + c;
        cnt = cvh.getCnt(segs[i].r + 1) + 1;
        cvh.add(line(-2 * segs[i + 1].l, (ll) segs[i + 1].l * segs[i + 1].l + val
                     - (ll) max(0, segs[i].r - segs[i + 1].l + 1) * max(0, segs[i].r - segs[i + 1].l + 1), cnt));
    }
    if (value)
        return val;
    return cnt;
}

ll solve(){
    segs.insert(segs.begin(), segment(-1, -1));

    ll l = 0, r = 1e18, best = -1;
    while (l <= r){
        ll mid = (l + r) >> 1;
        if (calc(mid) <= k){
            best = mid;
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    return calc(best, 1) - best * calc(best) - (min((ll) k, calc(best - 1)) - calc(best)) * (best - 1);
}

ll take_photos(int _n, int _m, int _k, vector<int> r, vector<int> c){
    n = _n;
    m = _m;
    k = _k;
    for(int i = 0; i < n; i++)
        segs.push_back(segment(min(r[i], c[i]), max(r[i], c[i])));

    prepare();
    return solve();
}

컴파일 시 표준 에러 (stderr) 메시지

aliens.cpp: In function 'll calc(ll, bool)':
aliens.cpp:102:13: warning: 'cnt' may be used uninitialized in this function [-Wmaybe-uninitialized]
  102 |     ll val, cnt;
      |             ^~~
#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...