제출 #1324762

#제출 시각아이디문제언어결과실행 시간메모리
1324762chithanhnguyenBubble Sort 2 (JOI18_bubblesort2)C++20
100 / 100
1680 ms59280 KiB
/*
Author: Nguyen Chi Thanh - High School for the Gifted - VNU.HCM (i2528)
*/
#ifndef NCTHANH
#include "bubblesort2.h"
#endif
#include <bits/stdc++.h>
using namespace std;

// #define int long long
#define ull unsigned long long
#define ld long double
#define pii pair<int, int>
#define fi first
#define se second
#define __builtin_popcount __builtin_popcountll
#define all(x) (x).begin(), (x).end()
#define BIT(x, i) (((x) >> (i)) & 1)
#define MASK(x) ((1ll << (x)))

#define debug(a, l, r) for (int _i = (l); _i <= (r); ++_i) cout << (a)[_i] << ' '; cout << '\n';

struct Normalize {
    vector<int> vals;

    void add(int v) {vals.push_back(v);}

    void build() {
        sort(all(vals));
        vals.erase(unique(all(vals)), end(vals));
    }

    int compress(int v) {
        return (int)(lower_bound(all(vals), v) - begin(vals)) + 1;
    }
};

struct FenwickTree {
    int n;
    vector<int> fen;

    FenwickTree(int _n) : n(_n), fen(n + 5, 0) {}

    void reset() {fill(all(fen), 0);}

    void update(int idx, int v) {
        for (int i = idx; i <= n; i += i & -i)
            fen[i] += v;
    }

    int get(int idx) {
        int sum = 0;
        for (int i = idx; i; i -= i & -i)
            sum += fen[i];
        return sum;
    }
};

vector<int> subtask12(vector<int> a, vector<int> x, vector<int> v) {
    int n = (int)a.size(), q = (int)x.size();

    // Compressing the values
    Normalize norm;
    {
        for (auto val : a) norm.add(val);
        for (auto val : v) norm.add(val);

        norm.build();
        for (int i = 0; i < n; ++i) a[i] = norm.compress(a[i]);
        for (int i = 0; i < q; ++i) v[i] = norm.compress(v[i]);
    }

    vector<int> res(q, 0);

    int sz = (int)norm.vals.size() + 5;
    FenwickTree fen(sz);
    for (int i = 0; i < q; ++i) {
        fen.reset();
        a[x[i]] = v[i];
        int ans = 0;
        for (int j = 0; j < n; ++j) {
            int contrib = fen.get(sz) - fen.get(a[j]);
            fen.update(a[j], 1);
            ans = max(ans, contrib);
        }
        res[i] = ans;
    }

    return res;
}

struct SegmentTree {
    int n; vector<int> st, lazy;

    SegmentTree(int _n) : n(_n), st(4 * n + 5, 0), lazy(4 * n + 5, 0) {}

    void apply(int id, int x) {
        st[id] += x;
        lazy[id] += x; 
    }

    void push(int id) {
        if (lazy[id] == 0) return;

        apply(id << 1, lazy[id]);
        apply(id << 1 | 1, lazy[id]);

        lazy[id] = 0;
    }

    void update(int id, int l, int r, int u, int v, int x) {
        if (v < l || r < u) return;
        if (u <= l && r <= v) {
            apply(id, x);
            return;
        }

        push(id);

        int mid = (l + r) >> 1;
        update(id << 1, l, mid, u, v, x);
        update(id << 1 | 1, mid + 1, r, u, v, x);

        st[id] = max(st[id << 1], st[id << 1 | 1]);
    }

    void update(int u, int v, int x) {
        if (u > v) return;
        update(1, 1, n, u, v, x);
    }

    int getmx() {return st[1];}
};

vector<int> full(vector<int> a, vector<int> x, vector<int> v) {
    int n = (int)a.size(), q = (int)x.size();
    vector<int> res(q, 0);

    vector<pii> data;
    for (int i = 0; i < n; ++i) data.push_back({a[i], i});
    for (int i = 0; i < q; ++i) data.push_back({v[i], x[i]});

    sort(all(data));
    data.erase(unique(all(data)), end(data));

    // for (auto &e : data) cout << e.fi << ' ' << e.se << '\n';

    int sz = (int)data.size() + 5;

    auto compress = [&] (pii x) {
        return (int)(lower_bound(all(data), x) - begin(data)) + 1;
    };  

    SegmentTree seg(sz);
    for (int i = 0; i < n; ++i) {
        a[i] = compress(pii{a[i], i});
        seg.update(a[i], a[i], i);
        seg.update(a[i] + 1, sz, -1);
    }

    for (int i = 0; i < q; ++i) {
        seg.update(a[x[i]], a[x[i]], -x[i]);
        seg.update(a[x[i]] + 1, sz, 1);

        v[i] = compress(pii{v[i], x[i]});
        a[x[i]] = v[i];
        seg.update(a[x[i]], a[x[i]], x[i]);
        seg.update(a[x[i]] + 1, sz, -1);

        // cout << seg.getmx() << '\n';
        res[i] = seg.getmx();
    }

    // cout << '\n';
    return res;
}

vector<int> countScans(vector<int> a, vector<int> x, vector<int> v) {
    int n = (int)a.size(), q = (int)x.size();

    vector<int> res;
    if (n <= 8000 && q <= 8000) res = subtask12(a, x, v);
    else res = full(a, x, v);

    return res;
}

#ifdef NCTHANH
signed main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr); cout.tie(nullptr);

    int n, q; cin >> n >> q;
    vector<int> a(n), x(q), v(q);
    for (int i = 0; i < n; ++i) cin >> a[i];
    for (int i = 0; i < q; ++i)
        cin >> x[i] >> v[i];

    vector<int> res = countScans(a, x, v);
    for (int i = 0; i < q; ++i) cout << res[i] << '\n'; 
    
    return 0;
}
#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...