Submission #1261373

#TimeUsernameProblemLanguageResultExecution timeMemory
1261373bluevioletK개의 묶음 (IZhO14_blocks)C++20
53 / 100
1096 ms14144 KiB
#include             <bits/stdc++.h>
    
#define             ll   long long
#define          io(x)   if (fopen(x".inp","r")) {freopen(x".inp","r",stdin),freopen(x".out","w",stdout);}
#define        TimeRun   {End=clock();cerr<<"Time run: "<<(float)(End-Begin)/CLOCKS_PER_SEC<<"s"<<el;}
#define      mem(c, x)   memset(c, x, sizeof(c))
#define         all(c)   c.begin(), c.end()
#define       bit(i,j)   ((i >> j) & 1)
#define             se   second     
#define             fi   first
#define             el   '\n'
using namespace std;  

template<class X, class Y> bool maximize(X &a, const Y &b) { return (a < b ? a = b, 1 : 0); }
template<class X, class Y> bool minimize(X &a, const Y &b) { return (a > b ? a = b, 1 : 0); }

int dx[8] = {0, 1, 0,-1, 1, 1,-1,-1};
int dy[8] = {1, 0,-1, 0, 1,-1,-1, 1};
const int  maxn  = 2e5 + 2;
const int  Inf   = 2e9 + 7;
const ll   Infll = 1e18 + 9;
const ll   Mod   = 1e9 + 7;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
int L[maxn], R[maxn], n, k, a[maxn];
ll rec[maxn << 2], lzRec[maxn << 2], cur[maxn << 2], lzCur[maxn << 2];

void downRec(int id, int l, int r) {
    minimize(lzRec[id << 1], lzRec[id]);
    minimize(lzRec[id << 1|1], lzRec[id]);
    minimize(rec[id << 1], lzRec[id]);
    minimize(rec[id << 1|1], lzRec[id]);
    lzRec[id] = Infll;
}
void downCur(int id, int l, int r) {
    minimize(lzCur[id << 1], lzCur[id]);
    minimize(lzCur[id << 1|1], lzCur[id]);
    minimize(cur[id << 1], lzCur[id]);
    minimize(cur[id << 1|1], lzCur[id]);
    lzCur[id] = Infll;
}

void buildCur(int id, int l, int r) {
    lzCur[id] = Infll;
    if (l == r) {
        cur[id] = Infll;
        return;
    }

    int mid = l + r >> 1; 
    buildCur(id << 1, l, mid);
    buildCur(id << 1|1, mid + 1, r);

    cur[id] = min(cur[id << 1], cur[id << 1|1]);
}
void buildRec(int id, int l, int r) {
    lzRec[id] = Infll;
    if (l == r) {
        if (l == 0) 
            rec[id] = 0;
        else
            rec[id] = Infll;
        return;
    }

    int mid = l + r >> 1; 
    buildRec(id << 1, l, mid);
    buildRec(id << 1|1, mid + 1, r);

    rec[id] = min(rec[id << 1], rec[id << 1|1]);
}
void updateCur(int id, int l, int r, int u, int v, ll val) {
    if (l > v || r < u) return;
    if (u <= l && r <= v) {
        minimize(cur[id], val);
        minimize(lzCur[id], val);
        return;
    }

    int mid = l + r >> 1; 
    downCur(id, l, r);
    updateCur(id << 1, l, mid, u, v, val);
    updateCur(id << 1|1, mid + 1, r, u, v, val);

    cur[id] = min(cur[id << 1], cur[id << 1|1]);
}

ll getRec(int id, int l, int r, int u, int v) {
    if (l > v || r < u) return Infll; 
    if (l >= u && r <= v) return rec[id];

    int mid = l + r >> 1; 
    downRec(id, l, r);
    ll get1 = getRec(id << 1, l, mid, u, v);
    ll get2 = getRec(id << 1|1, mid + 1, r, u, v);

    return min(get1, get2); 
}
ll getCur(int id, int l, int r, int u, int v) {
    if (l > v || r < u) return Infll; 
    if (l >= u && r <= v) return cur[id];

    int mid = l + r >> 1; 
    downCur(id, l, r);
    ll get1 = getCur(id << 1, l, mid, u, v);
    ll get2 = getCur(id << 1|1, mid + 1, r, u, v);

    return min(get1, get2); 
}

void buildLR() {
    stack<int> st;
    for (int i=1; i<=n; i++) {
        while (st.size() && a[st.top()] <= a[i]) st.pop();
        L[i] = (int)st.size() == 0 ? 1 : st.top() + 1;
        st.push(i);
    }
    while (st.size()) st.pop();
    for (int i=n; i>=1; i--) {
        while (st.size() && a[st.top()] <= a[i]) st.pop();
        R[i] = (int)st.size() == 0 ? n : st.top() - 1;
        st.push(i);
    }
}
void solve() {
    cin >> n >> k;
    for (int i=1; i<=n; i++) cin >> a[i];
    buildLR();
    buildCur(1, 0, n);
    buildRec(1, 0, n);

    for (int j=1; j<=k; j++) {
        for (int i=j; i<=n; i++) {
            ll minDp = getRec(1, j-1, n, L[i]-1, i-1) + a[i]; // get recent
            updateCur(1, j, n, i, R[i], minDp); // update current
        }
        if (j == k)
            return void(cout << getCur(1, j, n, n, n));

        // rec = cur
        for (int i=1; i<=n*4; i++) {
            rec[i] = cur[i];
            lzRec[i] = lzCur[i];

            cur[i] = Infll;
            lzCur[i] = Infll;
        }
    }
}

signed main() {
    
    ios_base::sync_with_stdio(false);  cin.tie(0); cout.tie(0); clock_t Begin = clock(), End;
    io("task"); 

    solve();
    
    TimeRun; return (0 ^ 0);
}

Compilation message (stderr)

blocks.cpp: In function 'int main()':
blocks.cpp:4:58: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
    4 | #define          io(x)   if (fopen(x".inp","r")) {freopen(x".inp","r",stdin),freopen(x".out","w",stdout);}
      |                                                   ~~~~~~~^~~~~~~~~~~~~~~~~~~
blocks.cpp:153:5: note: in expansion of macro 'io'
  153 |     io("task");
      |     ^~
blocks.cpp:4:85: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
    4 | #define          io(x)   if (fopen(x".inp","r")) {freopen(x".inp","r",stdin),freopen(x".out","w",stdout);}
      |                                                                              ~~~~~~~^~~~~~~~~~~~~~~~~~~~
blocks.cpp:153:5: note: in expansion of macro 'io'
  153 |     io("task");
      |     ^~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...