제출 #330056

#제출 시각아이디문제언어결과실행 시간메모리
330056lohacho휴가 (IOI14_holiday)C++14
100 / 100
1747 ms7392 KiB
#include"holiday.h"
#include <bits/stdc++.h>

using namespace std;

using LL = long long;
const LL MOD = (LL)1e9 + 7;
const LL NS = (LL)1e5 + 4;
LL N, ans, k, st;
vector<LL> srt;
LL a[NS];
LL cnt[NS * 4], sum[NS * 4];

void push(LL num, LL s, LL e, LL pos, LL val){
    if(pos < s || pos > e){
        return;
    }
    if(s == e){
        cnt[num] += val, sum[num] = cnt[num] * srt[s - 1];
        return;
    }
    push(num * 2, s, (s + e) / 2, pos, val);
    push(num * 2 + 1, (s + e) / 2 + 1, e, pos, val);
    cnt[num] = cnt[num * 2] + cnt[num * 2 + 1];
    sum[num] = sum[num * 2] + sum[num * 2 + 1];
}

pair<LL, LL> get(LL num, LL s, LL e, LL fs, LL fe, LL val){
    if(fe < s || fs > e || fs > fe || !val || !cnt[num]){
        return {0, 0};
    }
    if(s == e){
        return {min(val, cnt[num]), srt[s - 1] * min(val, cnt[num])};
    }
    if(s >= fs && e <= fe && cnt[num] <= val){
        return {cnt[num], sum[num]};
    }
    pair<LL, LL> r = get(num * 2 + 1, (s + e) / 2 + 1, e, fs, fe, val);
    if(r.first < val){
        pair<LL, LL> l = get(num * 2, s, (s + e) / 2, fs, fe, val - r.first);
        r.first += l.first, r.second += l.second;
    }
    return r;
}

void sol(LL ls, LL le, LL rs, LL re){
    if(rs > re || ls > le){
        return;
    }
    LL mid = (ls + le) >> 1;
    if(k - (st - mid) - (rs - mid) <= 0){
        sol(mid + 1, le, rs, re);
        return;
    }
    for(LL i = mid; i <= le; ++i){
        push(1, 1, (LL)srt.size(), a[i], 1);
    }
    pair<LL, LL> mx = {-MOD, -MOD};
    for(LL i = rs; i <= re; ++i){
        push(1, 1, (LL)srt.size(), a[i], 1);
        LL nval = get(1, 1, (LL)srt.size(), 1, (LL)srt.size(), max(0ll, k - (st - mid) - (i - mid))).second;
        ans = max(ans, nval);
        mx = max(mx, {nval, i});
    }
    for(LL i = rs; i <= re; ++i){
        push(1, 1, (LL)srt.size(), a[i], -1);
    }
    if(mid > ls){
        sol(ls, mid - 1, rs, mx.second);
    }
    for(LL i = mid; i <= le; ++i){
        push(1, 1, (LL)srt.size(), a[i], -1);
    }
    if(mid < le){
        for(LL i = rs; i < mx.second; ++i){
            push(1, 1, (LL)srt.size(), a[i], 1);
        }
        sol(mid + 1, le, mx.second, re);
        for(LL i = rs; i < mx.second; ++i){
            push(1, 1, (LL)srt.size(), a[i], -1);
        }
    }
}

LL findMaxAttraction(int n, int start, int d, int attraction[]) {
    N = n; k = d; st = start;
    for(LL i = 0; i < N; ++i){
        a[i] = attraction[i];
        srt.push_back(a[i]);
    }
    sort(srt.begin(), srt.end());
    srt.erase(unique(srt.begin(), srt.end()), srt.end());
    for(LL i = 0; i < N; ++i){
        a[i] = lower_bound(srt.begin(), srt.end(), a[i]) - srt.begin() + 1;
        if(d){
            ans = max(ans, srt[a[i] - 1]);
        }
    }
    sol(max(0, start - d), start, start + 1, N - 1);
    reverse(a, a + N);
    start = N - start - 1, st = start;
    sol(max(0, start - d), start, start + 1, N - 1);
    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...