답안 #853403

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
853403 2023-09-24T09:37:51 Z overwatch9 Meteors (POI11_met) C++17
100 / 100
2551 ms 65536 KB
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
using ull = unsigned long long;
struct stree {
    #define lc v*2
    #define rc v*2+1

    vector <ull> tree;
    stree() {}
    stree (int s) {
        tree.resize(4*s);
    }

    void pushdown(int v) {
        // since we're doing point query, we don't need to maintain
        // a separate pd variable
        if (tree[v] == 0)
            return;
        tree[lc] += tree[v];
        tree[rc] += tree[v];
        tree[v] = 0;
    }
    void update(int v, int tl, int tr, int l, int r, int val) {
        if (tl > r || tr < l)
            return;
        if (tl >= l && tr <= r) {
            tree[v] += val;
            return;
        }
        pushdown(v);
        int tm = (tl + tr) / 2;
        update(lc, tl, tm, l, r, val);
        update(rc, tm+1, tr, l, r, val);
    } 
    ull query(int v, int tl, int tr, int p) {
        if (tl > p || tr < p)
            return 0;
        if (tl == tr)
            return tree[v];
        pushdown(v);
        int tm = (tl + tr) / 2;
        if (p <= tm)
            return query(lc, tl, tm, p);
        else
            return query(rc, tm+1, tr, p);
    }

};
const int maxnmk = 3 * 1e5 + 1;
int n, m, k;
int owners[maxnmk], req[maxnmk], ans[maxnmk];
pair <pair <int, int>, int> updates[maxnmk];
priority_queue <pair <int, int>> q;
vector <vector <int>> subsets, stations;
int prev_mid = -1;
stree tree;
void search(int lo, int hi) {
    int mid = (lo + hi) / 2;
    if (prev_mid < mid) {
        for (int i = prev_mid+1; i <= mid; i++) {
            int l = updates[i].first.first;
            int r = updates[i].first.second;
            int val = updates[i].second;
            if (l <= r)
                tree.update(1, 0, m, l, r, val);
            else {
                tree.update(1, 0, m, l, m-1, val);
                tree.update(1, 0, m, 0, r, val);
            }
        }
    } else {
        for (int i = mid+1; i <= prev_mid; i++) {
            int l = updates[i].first.first;
            int r = updates[i].first.second;
            int val = updates[i].second;
            if (l <= r)
                tree.update(1, 0, m, l, r, -val);
            else {
                tree.update(1, 0, m, l, m-1, -val);
                tree.update(1, 0, m, 0, r, -val);
            }
        }
    }
    // check if any members have met their requirements
    bool added_lo = false, added_hi = false;
    for (auto i : subsets[mid]) {
        ull tot = 0;
        for (auto j : stations[i])
            tot += tree.query(1, 0, m, j);
        if (tot >= req[i]) {
            if (ans[i] == -1)
                ans[i] = mid;
            else
                ans[i] = min(ans[i], mid);
            if (lo != mid) {
                added_lo = true;
                subsets[(lo + mid) / 2].push_back(i);
            }
        } else {
            if (mid != hi) {
                added_hi = true;
                subsets[(mid+1 + hi) / 2].push_back(i);
            }
        }
    }
    if (added_lo)
        q.push({lo, mid});
    if (added_hi)
        q.push({mid+1, hi});
    prev_mid = mid;
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    fill(ans, ans + n, -1);
    stations.resize(n);
    for (int i = 0; i < m; i++) {
        cin >> owners[i];
        owners[i]--;
        stations[owners[i]].push_back(i);
    }
    for (int i = 0; i < n; i++)
        cin >> req[i];
    cin >> k;
    for (int i = 0; i < k; i++) {
        int l, r;
        ull val;
        cin >> l >> r >> val;
        l--; r--;
        updates[i].first.first = l;
        updates[i].first.second = r;
        updates[i].second = val;
    }
    q.push({0, k-1});
    subsets.resize(k);
    for (int i = 0; i < n; i++)
        subsets[(k-1)/2].push_back(i);
    tree = stree(m+1);
    while (!q.empty()) {
        int l = q.top().first;
        int r = q.top().second;
        q.pop();
        search(l, r);
    }
    for (int i = 0; i < n; i++) {
        if (ans[i] == -1)
            cout << "NIE\n";
        else
            cout << ans[i]+1 << '\n';
    }
}

Compilation message

met.cpp: In function 'void search(int, int)':
met.cpp:93:17: warning: comparison of integer expressions of different signedness: 'ull' {aka 'long long unsigned int'} and 'int' [-Wsign-compare]
   93 |         if (tot >= req[i]) {
      |             ~~~~^~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4440 KB Output is correct
2 Correct 2 ms 4440 KB Output is correct
3 Correct 3 ms 4440 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4440 KB Output is correct
2 Correct 3 ms 4444 KB Output is correct
3 Correct 3 ms 4696 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 91 ms 10320 KB Output is correct
2 Correct 165 ms 12464 KB Output is correct
3 Correct 225 ms 12060 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 180 ms 11392 KB Output is correct
2 Correct 197 ms 11296 KB Output is correct
3 Correct 179 ms 12728 KB Output is correct
4 Correct 61 ms 8272 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 92 ms 10804 KB Output is correct
2 Correct 138 ms 13248 KB Output is correct
3 Correct 32 ms 8080 KB Output is correct
4 Correct 192 ms 12368 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 112 ms 9816 KB Output is correct
2 Correct 192 ms 11492 KB Output is correct
3 Correct 126 ms 10320 KB Output is correct
4 Correct 224 ms 13908 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1334 ms 38968 KB Output is correct
2 Correct 492 ms 25436 KB Output is correct
3 Correct 199 ms 12624 KB Output is correct
4 Correct 2551 ms 59568 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1402 ms 37412 KB Output is correct
2 Correct 465 ms 25304 KB Output is correct
3 Correct 70 ms 11528 KB Output is correct
4 Correct 2495 ms 65536 KB Output is correct