답안 #944238

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
944238 2024-03-12T12:16:18 Z Zero_OP Meteors (POI11_met) C++14
74 / 100
3980 ms 46148 KB
#include<bits/stdc++.h>

using namespace std;
using int64 = int64_t;

#define     REP(i, n) for(int i = 0, _n = n; i < _n; ++i)
#define    REPD(i, n) for(int i = n - 1; i >= 0; --i)
#define  FOR(i, l, r) for(int i = l, _r = r; i <= _r; ++i)
#define FORD(i, r, l) for(int i = r, _l = l; i >= _l; --i)
#define          left __left
#define         right __right
#define          prev __prev
#define          next __next
#define           div __div
#define            pb push_back
#define            pf push_front
#define         sz(v) (int)v.size()
#define      range(v) begin(v), end(v)
#define    compact(v) v.erase(unique(range(v)), end(v))
#define      debug(v) "[" #v " = " << (v) << "]"

template<typename T>
    bool minimize(T& a, const T& b){
        if(a > b){
            a = b;
            return true;
        }
        return false;
    }

template<typename T>
    bool maximize(T& a, const T& b){
        if(a < b){
            a = b;
            return true;
        }
        return false;
    }

template<int dimension, class T>
struct vec : public vector<vec<dimension - 1, T>> {
    static_assert(dimension > 0, "Dimension must be positive !\n");
    template<typename... Args>
    vec(int n = 0, Args... args) : vector<vec<dimension - 1, T>>(n, vec<dimension - 1, T>(args...)) {}
};

template<class T>
struct vec<1, T> : public vector<T> {
    vec(int n = 0, T val = T()) : vector<T>(n, val) {}
};

void init(void);
void process(void);

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

    #define task "antuvu"
    if(fopen(task".inp", "r")){
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }

    int T = 1; //cin >> T;
    while(T--) {
        init();
        process();
    }

    return 0;
}

struct FenwickTree{
    vector<int64> bit;
    FenwickTree(int n) : bit(n + 1, 0) {}

    void update(int id, int val){
        for(; id < sz(bit); id += id & (-id)){
            bit[id] += val;
        }
    }

    int64 query(int id){
        int64 sum = 0;
        for(; id > 0; id -= id & (-id)){
            sum += bit[id];
        }
        return sum;
    }

    void update_range(int l, int r, int val){
        update(l, val);
        update(r + 1, -val);
    }
};

struct SegmentTree{
    vector<int64> st, lzy;
    SegmentTree(int n) : st(n << 2), lzy(n << 2) {}

    void reset(){
        fill(range(st), 0);
        fill(range(lzy), 0);
    }

    void apply(int id, int l, int r, int64 val){
        st[id] += 1LL * (r - l + 1) * val;
        lzy[id] += val;
    }

    void pushDown(int id, int l, int r, int mid){
        if(lzy[id]){
            apply(id << 1, l, mid, lzy[id]);
            apply(id << 1 | 1, mid + 1, r, lzy[id]);
            lzy[id] = 0;
        }
    }

    void update(int id, int l, int r, int u, int v, int val){
        if(u <= l and r <= v){
            apply(id, l, r, val);
        }
        else{
            int mid = l + r >> 1;
            pushDown(id, l, r, mid);
            if(u <= mid) update(id << 1, l, mid, u, v, val);
            if(mid < v) update(id << 1 | 1, mid + 1, r, u, v, val);
            st[id] = st[id << 1] + st[id << 1 | 1];
        }
    }

    int64 query(int id, int l, int r, int pos){
        if(l == r) return st[id];
        int mid = l + r >> 1;
        pushDown(id, l, r, mid);
        if(pos <= mid) return query(id << 1, l, mid, pos);
        else return query(id << 1 | 1, mid + 1, r, pos);
    }
};

const int MAX = 3e5 + 5;

int n, m, k, o[MAX], p[MAX], lq[MAX], rq[MAX], mq[MAX], ansq[MAX], l[MAX], r[MAX], a[MAX];
vector<int> owned_sections[MAX];

void init(){
    cin >> n >> m;
    FOR(i, 1, m){
        cin >> o[i];
        owned_sections[o[i]].pb(i);
    }

    FOR(i, 1, n){
        cin >> p[i];
    }

    cin >> k;
    FOR(i, 1, k){
        cin >> l[i] >> r[i] >> a[i];
    }
}

void parallel_binary_search(){
    FOR(i, 1, n){
        lq[i] = 1, rq[i] = k, ansq[i] = -1;
    }

    SegmentTree sections(m);

    while(true){
        vector<int> query_indices;
        FOR(i, 1, n){
            if(lq[i] <= rq[i]){
                mq[i] = (lq[i] + rq[i]) >> 1;
                query_indices.pb(i);
            }
        }

        if(query_indices.empty()) break;
        sort(range(query_indices), [&](int i, int j){
            return mq[i] < mq[j];
        });

        sections.reset();

        int j = 1;
        REP(i, sz(query_indices)){
            int id = query_indices[i];
            while(j <= mq[id]){
                if(l[j] <= r[j]){
                    sections.update(1, 1, m, l[j], r[j], a[j]);
                }
                else{
                    sections.update(1, 1, m, 1, r[j], a[j]);
                    sections.update(1, 1, m, l[j], m, a[j]);
                }
                ++j;
            }

            int64 sum = 0;
            for(int x : owned_sections[id]){
                sum += sections.query(1, 1, m, x);
            }

            if(sum >= p[id]){
                rq[id] = mq[id] - 1;
                ansq[id] = mq[id];
            }
            else lq[id] = mq[id] + 1;
        }
    }
}

void process(){
    parallel_binary_search();
    FOR(i, 1, n){
        if(ansq[i] == -1) cout << "NIE\n";
        else cout << ansq[i] << '\n';
    }
}

Compilation message

met.cpp: In member function 'void SegmentTree::update(int, int, int, int, int, int)':
met.cpp:124:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  124 |             int mid = l + r >> 1;
      |                       ~~^~~
met.cpp: In member function 'int64 SegmentTree::query(int, int, int, int)':
met.cpp:134:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  134 |         int mid = l + r >> 1;
      |                   ~~^~~
met.cpp: In function 'int main()':
met.cpp:60:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   60 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
met.cpp:61:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   61 |         freopen(task".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 17048 KB Output is correct
2 Correct 6 ms 16988 KB Output is correct
3 Correct 6 ms 17148 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 17236 KB Output is correct
2 Correct 6 ms 17052 KB Output is correct
3 Correct 7 ms 17168 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 316 ms 21340 KB Output is correct
2 Correct 387 ms 22256 KB Output is correct
3 Correct 374 ms 21852 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 362 ms 21856 KB Output is correct
2 Correct 355 ms 21588 KB Output is correct
3 Correct 394 ms 22244 KB Output is correct
4 Correct 71 ms 21336 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 162 ms 21340 KB Output is correct
2 Correct 263 ms 22412 KB Output is correct
3 Correct 64 ms 17500 KB Output is correct
4 Correct 374 ms 22032 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 155 ms 21328 KB Output is correct
2 Correct 329 ms 21592 KB Output is correct
3 Correct 336 ms 21596 KB Output is correct
4 Correct 389 ms 22288 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3847 ms 46148 KB Output is correct
2 Incorrect 1864 ms 42528 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3980 ms 45784 KB Output is correct
2 Incorrect 982 ms 41756 KB Output isn't correct
3 Halted 0 ms 0 KB -