Submission #1020327

# Submission time Handle Problem Language Result Execution time Memory
1020327 2024-07-11T23:46:51 Z esomer Colouring a rectangle (eJOI19_colouring) C++17
40 / 100
603 ms 45360 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll INF = 1e18;

struct segTree{
    vector<ll> v, pre, upd;
    int sz;
    void init(int n){
        sz = 1;
        while(sz < n) sz *= 2;
        v.assign(2 * sz, INF);
        upd.assign(2 * sz, 0);
        pre.assign(2 * sz, 2*INF);
    }
    void buildPre(vector<ll>& pr, int x, int lx, int rx){
        if(rx - lx == 1){
            if(lx >= (int)pr.size()){
                return;
            }
            pre[x] = -pr[lx] + INF;
            return;
        }
        int m = (lx + rx) / 2;
        buildPre(pr, 2 * x + 1, lx, m);
        buildPre(pr, 2 * x + 2, m, rx);
        v[x] = min(v[2 * x + 1], v[2 * x + 2]);
        pre[x] = min(pre[2 * x + 1], pre[2 * x + 2]);
    }
    void buildPre(vector<ll>& pr){
        buildPre(pr, 0, 0, sz);
    }
    void set(int l, int r, ll val, int x, int lx, int rx){
        if(lx >= l && rx <= r){
            upd[x] += val;
            v[x] += val;
            pre[x] += val;
            return;
        }else if(lx >= r || rx <= l) return;
        int m = (lx + rx) / 2;
        set(l, r, val, 2 * x + 1, lx, m);
        set(l, r, val, 2 * x + 2, m, rx);
        v[x] = min(v[2 * x + 1], v[2 * x + 2]) + upd[x];
        pre[x] = min(pre[2 * x + 1], pre[2 * x + 2]) + upd[x];
    }
    void set(int l, int r, ll val){
        set(l, r, val, 0, 0, sz);
    }
    ll calc(int l, int r, int x, int lx, int rx){
        if(lx >= l && rx <= r) return v[x];
        else if(lx >= r || rx <= l) return 2*INF;
        int m = (lx + rx) / 2;
        ll c1 = calc(l, r, 2 * x + 1, lx, m);
        ll c2 = calc(l, r, 2 * x + 2, m, rx);
        return min(c1, c2) + upd[x];
    }
    ll calc(int l, int r){
        return calc(l, r, 0, 0, sz);
    }
    ll calcPre(int l, int r, int x, int lx, int rx){
        if(lx >= l && rx <= r) return pre[x];
        else if(lx >= r || rx <= l) return 2*INF;
        int m = (lx + rx) / 2;
        ll c1 = calcPre(l, r, 2 * x + 1, lx, m);
        ll c2 = calcPre(l, r, 2 * x + 2, m, rx);
        return min(c1, c2) + upd[x];
    }
    ll calcPre(int l, int r){
        return calcPre(l, r, 0, 0, sz);
    }
};

ll getSum(int l, int r, vector<ll>& pre){
    if(l > r) return 0;
    if(l > 0) return pre[r] - pre[l-1];
    else return pre[r];
}

ll solve(int n, int m, vector<int>& down, vector<int>& up){
    // cout << "Down:\n";
    // for(int x : down) cout << x << " "; 
    // cout << "\n";
    // cout << "Up:\n";
    // for(int x : up) cout << x << " "; 
    // cout << "\n";
    vector<tuple<int, int, int>> inv;
    ll sum = 0;
    for(int i = m-1; i >= 0; i--){
        //Itero sobre els downs de la primera FILA, i m'agafo els rangs d'ups que comprenen.
        int s1 = m-i-1;
        int s2 = m-i-1 + (m-1 - (m-1-i)) * 2;
        s2 = min(s2, n+m-2);
        if(s1 > s2){
            //No hi ha cap rang, estic a alguna cantonada.
            // cout << "iSum "<< i << "\n";
            sum += down[i];
        }else{
            // cout << "i " << i << " s1 " << s1 << " s2 " << s2 << "\n";
            inv.push_back({s1, s2, down[i]});
        }
    }
    for(int i = n+m-2; i >= m; i--){
        //Itero sobre els downs de la primera COLUMNA, i m'agafo els rangs d'ups que comprenen.
        
        //Quan faig up, es conserva la suma. Per tant, jo vull veure a quina cel·la de la forma
        //(0, x) correspon (y, 0). -> x = y.
        int col1 = i-m+1; //Perquè la row és i-m+1.
        
        //Quan faig up, es conserva la suma. Per tant, jo vull veure a quina cel·la de la forma
        //(0, x) correspon (n-1, y). -> x = y+n-1.
        int y = n+m-2-i;
        int col2 = y+n-1;
        if(y >= m){
            //The cell (n-1, y) doesn't exist. Therefore, I want to find the cell
            //(0, x) with (k, m-1) -> x = m-1 + k.
            //Com quan baixo, la diferència es manté, i vaig de (i-m+1, 0) a (k, m-1),
            //tinc que i-m+1 = k-(m-1) -> k = i.
            col2 = m-1 + i;
        }
        col2 = min(col2, n+m-2);
        if(col1 > col2){
            // cout << "iSum "<< i << "\n";
            sum += down[i];
        }else{
            // cout << "i " << i << " col1 " << col1 << " col2 " << col2 << "\n";
            inv.push_back({col1, col2, down[i]});
        }
    }
    sort(inv.begin(), inv.end());
    segTree st; st.init(n+m);
    vector<ll> pre(n+m);
    pre[0] = 0;
    for(int i = 1; i < n+m; i++) pre[i] = pre[i-1] + up[i-1];
    st.buildPre(pre);
    st.set(0, 1, -INF);
    // cout << "sum " << sum << "\n";
    for(auto [l, r, cost] : inv){
        l++; r++; //I have it 1-indexed.
        /*
        El segment tree es guarda st[i] = el mínim cost si he comprat fins a i (em dona igual des d'on, perquè si he comprat
        és per algún rang anterior i ordeno per l, per tant he d'haver comprat des d'una j < l fins a i, i per tant tinc
        des de l fins a i ja comprats, i només he de comprar de i fins a r).
        El faig 1-indexed per considerar la possibilitat de no haver comprat cap.
        */


        //Segona transició, pago tots els ups. Puc o bé no pagar res, si ja he comprat fins a >= r, o bé pagar
        //prefix[r] - prefix[i] + st[i] per l <= i < r o bé st[i] + prefix[r] - prefix[l-1] per i < l. 
        //Per els que no pago res, els deixo igual, només he d'actualitzar st[r].
        ll mn = min(pre[r] + st.calcPre(l, r), st.calc(0, l) + getSum(l, r, pre));
        ll curr = st.calc(r, r + 1);
        if(curr > mn){
            st.set(r, r+1, mn-curr);
        }

        //Primera transició, simplement pago el preu del down, no compro res més, per tant tots es queden igual i els hi
        //sumo el preu del down.
        st.set(0, r, cost); //Els que ja són >= r no he de sumar res, es queden igual.
        
        // cout << "l " << l << " r " << r << " cost "<< cost << "\n";
        // for(int i = 0; i < n+m; i++){
        //     cout << "i " << i << " st "<< st.calc(i, i+1) << "\n";
        // }
    }
    // cout << "v[0] " << st.v[0] << " total " << st.v[0] + sum << "\n";
    return st.v[0] + sum;
}

int main(){
   ios_base::sync_with_stdio(0);
   cin.tie(0);

    /*
    Detall que no havia considerat. Realment, quan deixo de posar una down, i omplo amb ups, no estic
    omplint totes les caselles, només les de mateixa paritat, és una mica liada. Però, com les diagonals
    només cobreixen caselles de mateixa paritat, realment no és un problema, perquè vol dir que colorejar
    les caselles parelles i imparelles són dos problemes independents i puc fer el que tenia dos cops.*/

    int n, m; cin >> n >> m;
    vector<int> down(n+m-1);
    for(auto &i : down) cin >> i;
    vector<int> up(n+m-1);
    for(auto &i : up) cin >> i;
    vector<int> downOdd(n+m-1, 0), downEven(n+m-1, 0);
    int odd = (m-1)%2;;
    for(int i = 0; i < n + m - 1; i++){
        if(odd) downOdd[i] = down[i];
        else downEven[i] = down[i];
        odd ^= 1;
    }
    vector<int> upOdd(n+m-1, 0), upEven(n+m-1, 0);
    for(int i = 0; i < n + m - 1; i++){
        if(i%2) upOdd[i] = up[i];
        else upEven[i] = up[i];
    }
    ll ans = solve(n, m, downOdd, upOdd) + solve(n, m, downEven, upEven);
    cout << ans << "\n";
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 1 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 0 ms 348 KB Output is correct
8 Correct 0 ms 344 KB Output is correct
9 Correct 1 ms 348 KB Output is correct
10 Correct 0 ms 348 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 1 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 0 ms 348 KB Output is correct
8 Correct 0 ms 344 KB Output is correct
9 Correct 1 ms 348 KB Output is correct
10 Correct 0 ms 348 KB Output is correct
11 Correct 0 ms 348 KB Output is correct
12 Correct 0 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 0 ms 348 KB Output is correct
16 Correct 0 ms 348 KB Output is correct
17 Correct 0 ms 348 KB Output is correct
18 Correct 0 ms 348 KB Output is correct
19 Correct 0 ms 348 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 1 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 0 ms 348 KB Output is correct
8 Correct 0 ms 344 KB Output is correct
9 Correct 1 ms 348 KB Output is correct
10 Correct 0 ms 348 KB Output is correct
11 Correct 0 ms 348 KB Output is correct
12 Correct 0 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 0 ms 348 KB Output is correct
16 Correct 0 ms 348 KB Output is correct
17 Correct 0 ms 348 KB Output is correct
18 Correct 0 ms 348 KB Output is correct
19 Correct 0 ms 348 KB Output is correct
20 Correct 0 ms 348 KB Output is correct
21 Correct 1 ms 348 KB Output is correct
22 Correct 0 ms 348 KB Output is correct
23 Correct 1 ms 348 KB Output is correct
24 Correct 0 ms 348 KB Output is correct
25 Correct 0 ms 348 KB Output is correct
26 Correct 0 ms 348 KB Output is correct
27 Incorrect 0 ms 348 KB Output isn't correct
28 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 1 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 0 ms 348 KB Output is correct
8 Correct 0 ms 344 KB Output is correct
9 Correct 1 ms 348 KB Output is correct
10 Correct 0 ms 348 KB Output is correct
11 Correct 0 ms 348 KB Output is correct
12 Correct 0 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 0 ms 348 KB Output is correct
16 Correct 0 ms 348 KB Output is correct
17 Correct 0 ms 348 KB Output is correct
18 Correct 0 ms 348 KB Output is correct
19 Correct 0 ms 348 KB Output is correct
20 Correct 0 ms 348 KB Output is correct
21 Correct 1 ms 348 KB Output is correct
22 Correct 0 ms 348 KB Output is correct
23 Correct 1 ms 348 KB Output is correct
24 Correct 0 ms 348 KB Output is correct
25 Correct 0 ms 348 KB Output is correct
26 Correct 0 ms 348 KB Output is correct
27 Incorrect 0 ms 348 KB Output isn't correct
28 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 183 ms 22792 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 603 ms 45356 KB Output is correct
2 Correct 592 ms 45328 KB Output is correct
3 Correct 562 ms 45272 KB Output is correct
4 Correct 568 ms 45272 KB Output is correct
5 Correct 577 ms 45360 KB Output is correct
6 Correct 578 ms 45272 KB Output is correct
7 Correct 558 ms 45180 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 1 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 0 ms 348 KB Output is correct
8 Correct 0 ms 344 KB Output is correct
9 Correct 1 ms 348 KB Output is correct
10 Correct 0 ms 348 KB Output is correct
11 Correct 0 ms 348 KB Output is correct
12 Correct 0 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 0 ms 348 KB Output is correct
16 Correct 0 ms 348 KB Output is correct
17 Correct 0 ms 348 KB Output is correct
18 Correct 0 ms 348 KB Output is correct
19 Correct 0 ms 348 KB Output is correct
20 Correct 0 ms 348 KB Output is correct
21 Correct 1 ms 348 KB Output is correct
22 Correct 0 ms 348 KB Output is correct
23 Correct 1 ms 348 KB Output is correct
24 Correct 0 ms 348 KB Output is correct
25 Correct 0 ms 348 KB Output is correct
26 Correct 0 ms 348 KB Output is correct
27 Incorrect 0 ms 348 KB Output isn't correct
28 Halted 0 ms 0 KB -