제출 #712369

#제출 시각아이디문제언어결과실행 시간메모리
712369danikoynov사탕 분배 (IOI21_candies)C++17
100 / 100
1336 ms49632 KiB
#include "candies.h"

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
const ll inf = 1e18;

int n, q;

vector < int > s;
ll pref[maxn], cap[maxn];
vector < int > add[maxn], rem[maxn];

struct node
{
    ll max_val, min_val;

    node(ll _max_val = 0, ll _min_val = 0)
    {
        max_val = _max_val;
        min_val = _min_val;
    }
};

node tree[4 * maxn];
ll lazy[4 * maxn];

void push_lazy(int root, int left, int right)
{
    tree[root].max_val += lazy[root];
    tree[root].min_val += lazy[root];

    if (left != right)
    {
        lazy[root * 2] += lazy[root];
        lazy[root * 2 + 1] += lazy[root];
    }

    lazy[root] = 0;
}

node merge_node(node left, node right)
{
    node cur;
    cur.max_val = max(left.max_val, right.max_val);
    cur.min_val = min(left.min_val, right.min_val);
    return cur;
}

void update_range(int root, int left, int right, int qleft, int qright, ll val)
{
    push_lazy(root, left, right);
    if (left > qright || right < qleft)
        return;

    if (left >= qleft && right <= qright)
    {
        lazy[root] += val;
        push_lazy(root, left, right);
        return;
    }

    int mid = (left + right) / 2;
    update_range(root * 2, left, mid, qleft, qright, val);
    update_range(root * 2 + 1, mid + 1, right, qleft, qright, val);

    tree[root] = merge_node(tree[root * 2], tree[root * 2 + 1]);
}

node query(int root, int left, int right, int qleft, int qright)
{
    push_lazy(root, left, right);

    if (left > qright || right < qleft)
        return node(-inf, inf);

    if (left >= qleft && right <= qright)
        return tree[root];

    int mid = (left + right) / 2;
    return merge_node(query(root * 2, left, mid, qleft, qright),
                      query(root * 2 + 1, mid + 1, right, qleft, qright));

}

bool check(int pos, ll val)
{
    node ver = query(1, 0, q + 1, pos, q + 1);

    ll min_height = ver.min_val;
    ll max_height = ver.max_val;
   ///cout << pos << " : " << val << " : " << ver.max_val << " " << ver.min_val << endl;
    /**for (int i = pos; i < q + 2; i ++)
    {
        min_height = min(min_height, pref[i]);
        max_height = max(max_height, pref[i]);
    }*/
    return (max_height - val > min_height);
}


vector<int> distribute_candies(vector<int> c, vector<int> l,
                               vector<int> r, vector<int> v)
{
    n = c.size();
    q = l.size();
    s.resize(n, 0);
    for (int i = 0; i < n; i ++)
        cap[i] = c[i];
    for (int i = 0; i < q; i ++)
    {
        add[l[i]].push_back(i);
        rem[r[i]].push_back(i);
    }

    update_range(1, 0, q + 1, 0, q + 1, inf);
    update_range(1, 0, q + 1, 1, q + 1, -inf);

    ll fin = 0;
    for (int i = 0; i < n; i ++)
    {
        for (int idx : add[i])
        {
            ///cout << idx << endl;
            update_range(1, 0, q + 1, idx + 2, q + 1, v[idx]), fin += v[idx];
        }

        /**cout << "check " << i << endl;
        for (int j = 0; j < q + 2; j ++)
            cout << query(1, 0, q + 1, j, j).max_val << " ";
        cout << endl;*/
        /**pref[0] = inf;
        pref[1] = 0;
        for (int j = 0; j < q; j ++)
        {
            pref[j + 2] = pref[j + 1];
            if (l[j] <= i && r[j] >= i)
            {
                ///cout << "here" << endl;
                pref[j + 2] += v[j];
            }
        }*/
        /**for (int j = 0; j < q + 2; j ++)
            cout << pref[j] << " ";
        cout << endl;*/

        int lf = 1, rf = q + 1;
        while(lf <= rf)
        {
            int mf = (lf + rf) / 2;
            if (check(mf, c[i]))
                lf = mf + 1;
            else
                rf = mf - 1;
        }


        node ver = query(1, 0, q + 1, rf, q + 1);

        ll min_height = ver.min_val;
        ll max_height = ver.max_val;
        /**for (int i = pos; i < q + 2; i ++)
        {
            min_height = min(min_height, pref[i]);
            max_height = max(max_height, pref[i]);
        }*/

        //cout << "final " << min_height << " " << max_height << " " << rf << endl;
        ll base =query(1, 0, q + 1, rf, rf).max_val;
        //cout << base << " " << fin << " " << max_height <<  endl;
        if (max_height == query(1, 0, q + 1, rf, rf).max_val)
            s[i] = fin - min_height;
        else
            s[i] = fin - (max_height - c[i]);//, cout << "yes" << endl;

        for (int idx : rem[i])
        {
            ///cout << idx << endl;
            update_range(1, 0, q + 1, idx + 2, q + 1, -v[idx]), fin -= v[idx];
        }

    }

    return s;
}

컴파일 시 표준 에러 (stderr) 메시지

candies.cpp: In function 'std::vector<int> distribute_candies(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
candies.cpp:171:12: warning: unused variable 'base' [-Wunused-variable]
  171 |         ll base =query(1, 0, q + 1, rf, rf).max_val;
      |            ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...