답안 #970517

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
970517 2024-04-26T16:19:07 Z Whisper 구경하기 (JOI13_watching) C++17
100 / 100
946 ms 600 KB
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using ll = long long;

//#define int long long
#define FOR(i, a, b) for (int i = a; i <= b; i++)
#define FORD(i, a, b) for (int i = b; i >= a; i --)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPD(i, n) for (int i = n - 1; i >= 0; --i)

#define MASK(i) (1LL << (i))
#define BIT(x, i) (((x) >> (i)) & 1)

constexpr ll LINF = (1ll << 60);
constexpr int INF = (1ll << 30);
constexpr int Mod = 1e9 + 7;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

void setupIO(){
    #define name "Whisper"
    //Phu Trong from Nguyen Tat Thanh High School for gifted student
    srand(time(NULL));
    cin.tie(nullptr)->sync_with_stdio(false); cout.tie(nullptr);
    //freopen(name".inp", "r", stdin);
    //freopen(name".out", "w", stdout);
    cout << fixed << setprecision(10);
}

template <class X, class Y>
    bool minimize(X &x, const Y &y){
        X eps = 1e-9;
        if (x > y + eps) {x = y; return 1;}
        return 0;
    }

template <class X, class Y>
    bool maximize(X &x, const Y &y){
        X eps = 1e-9;
        if (x + eps < y) {x = y; return 1;}
        return 0;
    }
int nArr, nSmall, nBig;
const int MAX = 2e3 + 1;

int a[MAX];
struct MonotonicQueue: deque<pair<int, int>>{
    void push(int x, int i){
        while (!empty() && back().first >= x) pop_back();
        push_back({x, i});
    }
    void pop(int i){
        if(!empty() && front().second == i) pop_front();
    }
    int get_front(){
        return front().first;
    }
    int get_back(){
        return back().first;
    }
};
void Whisper(){
    cin >> nArr >> nSmall >> nBig;
    for (int i = 1; i <= nArr; ++i) cin >> a[i];
    if (nSmall + nBig >= nArr) return void(cout << 1);

    sort(a + 1, a + nArr + 1);


    auto checkSmall = [&](int w){
        vector<vector<int>> dp(2, vector<int>(nArr + 1, INF));
        int ans = INF;
        for (int v = 0; v <= nSmall; ++v){
            MonotonicQueue light, heavy;
            dp[0][0] = 0;
            if(v > 0)
                light.push(dp[1][0], 0);
            heavy.push(dp[0][0], 0);
            for (int i = 1; i <= nArr; ++i){
                if(v > 0)
                    minimize(dp[0][i], dp[1][i - 1]);
                minimize(dp[0][i], dp[0][i - 1] + 1);

                while (!light.empty() && a[i] - a[light.front().second + 1] + 1 > w) light.pop_front();
                while (!heavy.empty() && a[i] - a[heavy.front().second + 1] + 1 > 2 * w) heavy.pop_front();

                if(!light.empty()) minimize(dp[0][i], light.get_front());
                if(!heavy.empty()) minimize(dp[0][i], heavy.get_front() + 1);

                if(v > 0)
                    light.push(dp[1][i], i);
                heavy.push(dp[0][i], i);
            }
            minimize(ans, dp[0][nArr]);
            swap(dp[0], dp[1]);
            for (int i = 1; i <= nArr; ++i) dp[0][i] = INF;
        }
        return (ans <= nBig);
    };
    auto checkBig = [&](int w){
        vector<vector<int>> dp(2, vector<int>(nArr + 1, INF));
        int ans = INF;
        for (int v = 0; v <= nBig; ++v){
            MonotonicQueue light, heavy;
            dp[0][0] = 0;
            if(v > 0)
                heavy.push(dp[1][0], 0);
            light.push(dp[0][0], 0);
            for (int i = 1; i <= nArr; ++i){
                if(v > 0)
                    minimize(dp[0][i], dp[1][i - 1]);
                minimize(dp[0][i], dp[0][i - 1] + 1);

                while (!light.empty() && a[i] - a[light.front().second + 1] + 1 > w) light.pop_front();
                while (!heavy.empty() && a[i] - a[heavy.front().second + 1] + 1 > 2 * w) heavy.pop_front();

                if(!light.empty()) minimize(dp[0][i], light.get_front() + 1);
                if(!heavy.empty()) minimize(dp[0][i], heavy.get_front());

                if(v > 0)
                    heavy.push(dp[1][i], i);
                light.push(dp[0][i], i);
            }
            minimize(ans, dp[0][nArr]);
            swap(dp[0], dp[1]);
            for (int i = 1; i <= nArr; ++i) dp[0][i] = INF;
        }
        return (ans <= nSmall);
    };
    int l = 0, r = *max_element(a + 1, a + nArr + 1) + 1;
    int ans = -1;

    while (r - l > 1){
        int mid = (l + r) >> 1;
        int f = (nBig > nSmall ? checkSmall(mid) : checkBig(mid));
        if(f) r = mid, ans = mid;
        else l = mid;
    }

    cout << ans;
}


signed main(){
    setupIO();
    int Test = 1;
//    cin >> Test;
    for ( int i = 1 ; i <= Test ; i++ ){
        Whisper();
        if (i < Test) cout << '\n';
    }
}


# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 344 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 0 ms 348 KB Output is correct
7 Correct 1 ms 348 KB Output is correct
8 Correct 1 ms 348 KB Output is correct
9 Correct 1 ms 348 KB Output is correct
10 Correct 1 ms 348 KB Output is correct
11 Correct 1 ms 348 KB Output is correct
12 Correct 3 ms 348 KB Output is correct
13 Correct 1 ms 348 KB Output is correct
14 Correct 0 ms 348 KB Output is correct
15 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 600 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 1 ms 348 KB Output is correct
5 Correct 1 ms 348 KB Output is correct
6 Correct 1 ms 348 KB Output is correct
7 Correct 14 ms 344 KB Output is correct
8 Correct 138 ms 348 KB Output is correct
9 Correct 149 ms 476 KB Output is correct
10 Correct 92 ms 348 KB Output is correct
11 Correct 110 ms 348 KB Output is correct
12 Correct 946 ms 496 KB Output is correct
13 Correct 13 ms 600 KB Output is correct
14 Correct 13 ms 344 KB Output is correct
15 Correct 16 ms 344 KB Output is correct