답안 #1071879

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1071879 2024-08-23T12:03:59 Z Boas 사탕 분배 (IOI21_candies) C++17
100 / 100
2403 ms 52040 KB
#include "candies.h"

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef vector<int> vi;
typedef signed i32;
typedef vector<i32> vi32;
typedef vector<bool> vb;
typedef vector<vi> vvi;
typedef set<int> si;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<vii> vvii;
#define pb push_back
#define loop(x, i) for (int i = 0; i < x; i++)
#define ALL(x) begin(x), end(x)
#define sz(x) (int)x.size()

bool debug = 0;
class node
{
public:
    int sufMax = 0, sufMin = 0, mxIx = 0, mnIx = 0;
    node operator+(const node &b) const
    {
        node res;
        if (this->sufMax == LLONG_MIN / 2)
            return b;
        if (b.sufMax == LLONG_MIN / 2)
            return *this;
        if (this->sufMin < b.sufMin)
        {
            res.sufMin = this->sufMin;
            res.mnIx = this->mnIx;
        }
        else
        {
            res.sufMin = b.sufMin;
            res.mnIx = b.mnIx;
        }
        if (this->sufMax > b.sufMax)
        {
            res.sufMax = this->sufMax;
            res.mxIx = this->mxIx;
        }
        else
        {
            res.sufMax = b.sufMax;
            res.mxIx = b.mxIx;
        }
        return res;
    }
    node &operator+=(const int &v)
    {
        this->sufMin += v;
        this->sufMax += v;
        return *this;
    }
    bool operator==(const node &b)
    {
        return b.sufMax == this->sufMax &&
               b.sufMin == this->sufMin;
    }
};

node def = {LLONG_MIN / 2, LLONG_MAX / 2, 0, 0}; // default

vector<node> tree;
vi lazy;
vi treeArr;

int treeSz = 1;

void propagate(int i)
{
    tree[i] += lazy[i];
    if (i < treeSz)
    {
        lazy[2 * i] += lazy[i];
        // tree[2 * i] += lazy[i]; // new
        lazy[2 * i + 1] += lazy[i];
        // tree[2 * i + 1] += lazy[i]; // new
    }
    lazy[i] = {};
}

node get(int i, int l, int r, int ql, int qr)
{
    if (qr < l || r < ql)
        return def;
    node res = def;

    if (debug)
    {
        for (int ix = max(ql, l); ix <= min(qr, r); ix++)
        {
            if (treeArr[ix] > res.sufMax)
            {
                res.sufMax = treeArr[ix];
                res.mxIx = ix;
            }
            if (treeArr[ix] < res.sufMin)
            {
                res.sufMin = treeArr[ix];
                res.mnIx = ix;
            }
        }
    }
    int m = l + (r - l) / 2;
    propagate(i);
    if (ql <= l && r <= qr)
    {
        if (debug)
            assert(tree[i] == res);
        return tree[i];
    }

    auto res2 = get(2 * i, l, m, ql, qr) +
                get(2 * i + 1, m + 1, r, ql, qr);
    if (debug)
        assert(res == res2);
    return res2;
}

void add(int i, int l, int r, int ql, int qr, int v)
{
    if (debug && i == 1)
    {
        for (int ix = ql; ix <= qr; ix++)
        {
            treeArr[ix] += v;
        }
    }

    propagate(i);
    if (qr < l || r < ql)
        return;
    int m = l + (r - l) / 2;
    if (ql <= l && r <= qr)
    {
        lazy[i] += v;
        propagate(i); // dit miste
        return;
    }
    add(2 * i, l, m, ql, qr, v);
    add(2 * i + 1, m + 1, r, ql, qr, v);
    tree[i] = tree[2 * i] + tree[2 * i + 1]; // dit miste
}

vi32 distribute_candies(vi32 c, vi32 l, vi32 r, vi32 v)
{
    int n = sz(c);
    int q = sz(l);

    if (debug)
        treeArr = vi(q + 1);
    while (treeSz <= q)
        treeSz *= 2;
    tree.resize(treeSz * 2);
    lazy.resize(treeSz * 2);
    loop(treeSz, i)
    {
        tree[treeSz + i].mxIx = i;
        tree[treeSz + i].mnIx = i;
    }
    for (int i = treeSz - 1; i >= 1; i--)
    {
        tree[i] = tree[2 * i] + tree[2 * i + 1];
    }
    vvi queryBegin(n), queryEnd(n);
    loop(q, i)
    {
        queryBegin[l[i]].pb(i);
        queryEnd[r[i]].pb(i);
    }
    vi32 s(n);
    loop(n, i)
    {
        for (int j : queryBegin[i])
        {
            add(1, 0, treeSz - 1, 0, j, v[j]);
        }
        int lo = 0, hi = q;
        while (hi > lo)
        {
            int m = lo + (hi - lo + 1) / 2;
            node res = get(1, 0, treeSz - 1, m, q);
            int d = res.sufMax - res.sufMin;
            if (d >= c[i])
            {
                lo = m;
            }
            else
                hi = m - 1;
        }
        node res = get(1, 0, treeSz - 1, hi, q);
        int d = res.sufMax - res.sufMin;
        if (d >= c[i])
        {
            if (hi == res.mxIx)
            {
                s[i] = c[i] + (i32)res.sufMin;
                if (debug)
                    assert(s[i] >= 0);
            }
            else
            {
                s[i] = (i32)res.sufMax;
                if (debug)
                    assert(s[i] >= 0);
            }
        }
        else
        {
            s[i] = (i32)res.sufMax;
        }
        for (int j : queryEnd[i])
        {
            add(1, 0, treeSz - 1, 0, j, -v[j]);
        }
    }
    return s;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 600 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
3 Correct 2 ms 604 KB Output is correct
4 Correct 2 ms 600 KB Output is correct
5 Correct 8 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1763 ms 50000 KB Output is correct
2 Correct 1920 ms 49424 KB Output is correct
3 Correct 2011 ms 49208 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 233 ms 34132 KB Output is correct
3 Correct 760 ms 14932 KB Output is correct
4 Correct 2403 ms 51256 KB Output is correct
5 Correct 2204 ms 51656 KB Output is correct
6 Correct 1742 ms 52040 KB Output is correct
7 Correct 1726 ms 51384 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
3 Correct 167 ms 31564 KB Output is correct
4 Correct 628 ms 13656 KB Output is correct
5 Correct 1766 ms 44064 KB Output is correct
6 Correct 1688 ms 44472 KB Output is correct
7 Correct 1483 ms 45312 KB Output is correct
8 Correct 1802 ms 43960 KB Output is correct
9 Correct 2016 ms 45496 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 600 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
3 Correct 2 ms 604 KB Output is correct
4 Correct 2 ms 600 KB Output is correct
5 Correct 8 ms 860 KB Output is correct
6 Correct 1763 ms 50000 KB Output is correct
7 Correct 1920 ms 49424 KB Output is correct
8 Correct 2011 ms 49208 KB Output is correct
9 Correct 1 ms 344 KB Output is correct
10 Correct 233 ms 34132 KB Output is correct
11 Correct 760 ms 14932 KB Output is correct
12 Correct 2403 ms 51256 KB Output is correct
13 Correct 2204 ms 51656 KB Output is correct
14 Correct 1742 ms 52040 KB Output is correct
15 Correct 1726 ms 51384 KB Output is correct
16 Correct 1 ms 348 KB Output is correct
17 Correct 1 ms 348 KB Output is correct
18 Correct 167 ms 31564 KB Output is correct
19 Correct 628 ms 13656 KB Output is correct
20 Correct 1766 ms 44064 KB Output is correct
21 Correct 1688 ms 44472 KB Output is correct
22 Correct 1483 ms 45312 KB Output is correct
23 Correct 1802 ms 43960 KB Output is correct
24 Correct 2016 ms 45496 KB Output is correct
25 Correct 1 ms 348 KB Output is correct
26 Correct 699 ms 13716 KB Output is correct
27 Correct 232 ms 33872 KB Output is correct
28 Correct 2218 ms 49888 KB Output is correct
29 Correct 1895 ms 50292 KB Output is correct
30 Correct 1860 ms 50480 KB Output is correct
31 Correct 1809 ms 50536 KB Output is correct
32 Correct 1737 ms 50744 KB Output is correct