답안 #435917

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
435917 2021-06-23T23:36:15 Z illyakr 사탕 분배 (IOI21_candies) C++17
40 / 100
1014 ms 24868 KB
#include <bits/stdc++.h>
#include "candies.h"
using namespace std;
#define ll long long

vector<int> res;
int n, q;
bool scbl = true;
ll _res[201010];
ll t[801010];
ll tAdd[801010];
ll tPress[801010];
pair<ll, ll> Up[201010];
ll Sv;
void push(int v, int vl, int vr) {
    if (tPress[v] == -1 && tAdd[v] == 0)return;
    if (vl == vr) {
        if (tPress[v] != -1){t[v] = tPress[v];t[v] = min(t[v], Up[vl].first);}
        if (tAdd[v] != 0)t[v] += tAdd[v];
        if (t[v] < 0 || t[v] > Up[vl].first) {
            exit(1);
        }
    } else {
        if (tPress[v] != -1) {
            tAdd[2 * v] = tAdd[v];
            tPress[2 * v] = tPress[v];

            tAdd[2 * v + 1] = tAdd[v];
            tPress[2 * v + 1] = tPress[v];
        } else if (tAdd[v] != 0) {
            tAdd[2 * v] += tAdd[v];
            tAdd[2 * v + 1] += tAdd[v];
        }
    }
    tPress[v] = -1; tAdd[v] = 0;
}
void updAdd(int v, int vl, int vr, int l, int r, ll val) {
    push(v, vl, vr);
    if (l <= vl && vr <= r) {
        tAdd[v] += val;
        push(v, vl, vr);
        return;
    }
    if (r < vl || vr < l)return;
    int vm = (vl + vr) / 2;
    updAdd(2 * v, vl, vm, l, r, val);
    updAdd(2 * v + 1, vm + 1, vr, l, r, val);
}
void updPress(int v, int vl, int vr, int l, int r, ll val) {
    push(v, vl, vr);
    if (l <= vl && vr <= r) {
        tPress[v] = val;
        push(v, vl, vr);
        return;
    }
    if (r < vl || vr < l)return;
    int vm = (vl + vr) / 2;
    updPress(2 * v, vl, vm, l, r, val);
    updPress(2 * v + 1, vm + 1, vr, l, r, val);
}
int gt(int v, int vl, int vr, int pos) {
    push(v, vl, vr);
    if (vl == vr)return t[v];
    int vm = (vl + vr) / 2;
    if (pos <= vm)return gt(2 * v, vl, vm, pos);
    return gt(2 * v + 1, vm + 1, vr, pos);
}

void cl(int &P) {
    if (P < 0)P = 0;
    if (P > Sv)P %= Sv;
}
void Psh(int v, int vl, int vr) {
    if (tAdd[v] == 0)return;
    if (vl != vr) {
        tAdd[2 * v] += tAdd[v];
        tAdd[2 * v + 1] += tAdd[v];


        if (tAdd[2 * v] < 0)tAdd[2 * v] = 0;
        if (tAdd[2 * v] > Sv){tAdd[2 * v] %= Sv; if (tAdd[2 * v] == 0)tAdd[2 * v] += Sv;}

        if (tAdd[2 * v + 1] < 0)tAdd[2 * v + 1] = 0;
        if (tAdd[2 * v + 1] > Sv){tAdd[2 * v + 1] %= Sv; if (tAdd[2 * v + 1] == 0)tAdd[2 * v + 1] += Sv;}
        tAdd[v] = 0;
        return;
    }
}
void tr(int v, int vl, int vr, int l, int r, int val) {
    Psh(v, vl, vr);
    if (l <= vl && vr <= r) {
        tAdd[v] += val;
        Psh(v, vl, vr);
        return;
    }
    if (r < vl || vr < l)return;
    int vm = (vl + vr) / 2;
    tr(2 * v, vl, vm, l, r, val);
    tr(2 * v + 1, vm + 1, vr, l, r, val);
}
int GGT(int v, int vl, int vr, int pos) {
    Psh(v, vl, vr);
    if (vl == vr)return tAdd[v];
    int vm = (vl + vr) / 2;
    if (pos <= vm)return GGT(2 * v, vl, vm, pos);
    return GGT(2 * v + 1, vm + 1, vr, pos);
}

bool frbl = true;
std::vector<int> distribute_candies(std::vector<int> c, std::vector<int> l,
                                    std::vector<int> r, std::vector<int> v) {
    n = c.size(); q = v.size();
    res.resize(n, 0);
    for (int i = 0; i < q; i++)
        if (v[i] < 0){scbl = false;break;}
    for (int i = 0; i < q; i++)
        if (l[i] != 0 || r[i] != n - 1){frbl = false;break;}

    if (n * q <= 100000000) {
        for (int i = 0; i < q; i++) {
            for (int j = l[i]; j <= r[i]; j++) {
                res[j] += v[i];
                if (res[j] < 0)res[j] = 0;
                else if (res[j] > c[j])res[j] = c[j];
            }
        }
        return res;
    }
    if (scbl) {
        for (int i = 0; i < q; i++) {
            _res[l[i]] += v[i];
            _res[r[i] + 1] -= v[i];
        }
        for (int i = 1; i < n; i++)
            _res[i] += _res[i - 1];
        for (int i = 0; i < n; i++) {
            _res[i] = min(_res[i], (ll)c[i]);
            res[i] = _res[i];
        }
        return res;
    }
    if (frbl) {
        for (int i = 0; i < n; i++)
            Up[i] = {c[i], i};
        sort(Up, Up + n, [](pair<ll, ll> q, pair<ll, ll> w) {
             return q.first < w.first;
        });
        memset(tPress, -1, sizeof(tPress));
        for (int id = 0; id < q; id++) {
            int AllLeft = -1;
            {
                int l = -1, r = n;
                while (l + 1 < r) {
                    int mid = (l + r) / 2;
                    int el = gt(1, 0, n - 1, mid);

                    if (el + v[id] <= 0 || el + v[id] >= Up[mid].first)l = mid;
                    else r = mid;
                }
                AllLeft = l;
            }
            if (v[id] < 0) {
                if (AllLeft != -1)updPress(1, 0, n - 1, 0, AllLeft, 0);
                if (AllLeft != n - 1)updAdd(1, 0, n - 1, AllLeft + 1, n - 1, v[id]);
            } else {
                if (AllLeft != -1)updPress(1, 0, n - 1, 0, AllLeft, 101010101010101010);
                if (AllLeft != n - 1)updAdd(1, 0, n - 1, AllLeft + 1, n - 1, v[id]);
            }
        }
        for (int i = 0; i < n; i++)
            res[Up[i].second] = gt(1, 0, n - 1, i);
        return res;
    }
    Sv = c[0];
    for (int i = 0; i < q; i++)
        tr(1, 0, n - 1, l[i], r[i], v[i]);
    for (int i = 0; i < n; i++)
        res[i] = GGT(1, 0, n - 1, i);
    return res;
}

/**
5
10 10 10 10 10
3
1 4 5
0 3 6
0 4 -7




3
10 15 13
2
0 2 20
0 1 -11


0 4 13
*/
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 1 ms 316 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 7 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 152 ms 9772 KB Output is correct
2 Correct 125 ms 9704 KB Output is correct
3 Correct 121 ms 9696 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Incorrect 155 ms 5072 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 354 ms 11412 KB Output is correct
4 Correct 115 ms 20272 KB Output is correct
5 Correct 918 ms 24808 KB Output is correct
6 Correct 920 ms 24868 KB Output is correct
7 Correct 1014 ms 24772 KB Output is correct
8 Correct 901 ms 24724 KB Output is correct
9 Correct 125 ms 9668 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 1 ms 316 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 7 ms 332 KB Output is correct
6 Correct 152 ms 9772 KB Output is correct
7 Correct 125 ms 9704 KB Output is correct
8 Correct 121 ms 9696 KB Output is correct
9 Correct 1 ms 204 KB Output is correct
10 Incorrect 155 ms 5072 KB Output isn't correct
11 Halted 0 ms 0 KB -