답안 #970522

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
970522 2024-04-26T16:22:16 Z vjudge1 구경하기 (JOI13_watching) C++17
100 / 100
959 ms 588 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 348 KB Output is correct
3 Correct 0 ms 416 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
6 Correct 1 ms 344 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 344 KB Output is correct
10 Correct 2 ms 344 KB Output is correct
11 Correct 1 ms 344 KB Output is correct
12 Correct 3 ms 348 KB Output is correct
13 Correct 1 ms 344 KB Output is correct
14 Correct 1 ms 348 KB Output is correct
15 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 348 KB Output is correct
4 Correct 1 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 14 ms 500 KB Output is correct
8 Correct 138 ms 480 KB Output is correct
9 Correct 158 ms 348 KB Output is correct
10 Correct 91 ms 348 KB Output is correct
11 Correct 94 ms 348 KB Output is correct
12 Correct 959 ms 588 KB Output is correct
13 Correct 13 ms 348 KB Output is correct
14 Correct 14 ms 348 KB Output is correct
15 Correct 16 ms 344 KB Output is correct