QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#168262#7108. Couleurucup-team859RE 0ms0kbC++145.2kb2023-09-08 02:35:332023-09-08 02:35:35

Judging History

你现在查看的是最新测评结果

  • [2023-09-08 02:35:35]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2023-09-08 02:35:33]
  • 提交

answer

#include <bits/stdc++.h>

#define lsb(x) (x & (-x))

using ull = unsigned long long;
using ll = long long;

using namespace std;

struct SegTree {
    struct Node {
        int l = -1, r = -1;
        int count = 0;
    };

    SegTree() {
        makeNode();
    }

    inline int makeNode(int oldId) {
        if (oldId == -1) {
            return makeNode();
        }
        data.push_back(data[oldId]);
        return (int)data.size() - 1;
    }

    inline int makeNode() {
        data.emplace_back();
        return (int)data.size() - 1;
    }

    int update(int id, int l, int r, int qpos) {
        int newId = makeNode(id);

        if (l == r) {
            data[newId].count++;
        } else {
            int mid = (l + r) / 2;

            if (qpos <= mid) data[newId].l = update(data[newId].l, l, mid, qpos);
            else data[newId].r = update(data[newId].r, mid + 1, r, qpos);

            data[newId].count = 0;
            if (data[newId].l != -1) {
                data[newId].count += data[data[newId].l].count;
            }
            if (data[newId].r != -1) {
                data[newId].count += data[data[newId].r].count;
            }
        }

        // cerr << newId << " " << l << " " << r << " " << data[newId].count << " --> "
        //     << data[data[newId].l].count << " " << data[data[newId].r].count << "\n"; 
 
        return newId;
    }

    int query(int id, int l, int r, int ql, int qr) {
        if (id == -1 || ql > qr) return 0;

        if (ql <= l && r <= qr) {
            return data[id].count;
        } else {
            int mid = (l + r) / 2;
            int count = 0;

            if (ql <= mid) count += query(data[id].l, l, mid, ql, qr);
            if (mid < qr) count += query(data[id].r, mid + 1, r, ql, qr);

            return count;
        }
    }

    vector<Node> data;
};

int main() {
#ifdef HOME
    ifstream cin("input.in");
    ofstream cout("output.out");
#endif
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int t;
    cin >> t;
    for (int tt = 1; tt <= t; tt++) {
        int n;
        cin >> n;

        vector<int> a(n + 1);
        vector<vector<int>> ids(n + 1);
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            ids[a[i]].push_back(i);
        }

        SegTree st;

        vector<int> roots(n + 1);
        for (int i = 1; i <= n; i++) {
            roots[i] = roots[i - 1];
            for (auto pos : ids[i]) {
                roots[i] = st.update(roots[i], 1, n, pos);
            }
        }

        auto Get = [&](int l, int r, int low, int high) {
            if (low > high) return 0;
            return st.query(roots[high], 1, n, l, r) - st.query(roots[low - 1], 1, n, l, r);
        };
        
        ll answer = 0;
        for (int i = 1; i <= n; i++) {
            answer += Get(1, i - 1, a[i] + 1, n);
        }

        multiset<ll> costs;
        costs.insert(answer);

        set<pair<int, ll>> segs;
        segs.insert({1, answer});
        
        set<int> rem;
        rem.insert(0);
        rem.insert(n + 1);

        for (int i = 1; i <= n; i++) {
            ll p;
            cin >> p;

            answer = *prev(costs.end());
            cout << answer << " ";
            p ^= answer;

            // cerr << "p, answer ---> " << p << " " << answer << "\n";

            auto itr = rem.insert(p).first;
            auto prv = prev(itr);
            auto nxt = next(itr);

            int l = *prv + 1;
            int r = *nxt - 1;
            // cerr << "l, r ---> " << l << " " << r << "\n";

            auto seg_itr = segs.upper_bound({l, -1});
            auto seg = *seg_itr;
            segs.erase(seg_itr);

            ll curr = seg.second, currL = 0, currR = 0;
            costs.erase(costs.find(curr));

            if (p - l < r - p) {
                currR = curr;
                for (int j = l; j < p; j++) {
                    currL += Get(l, j - 1, a[j] + 1, n);
                    currR -= Get(p, r, 1, a[j] - 1);
                }
                currR -= currL;
                currR -= Get(p + 1, r, 1, a[p] - 1);
            } else {
                currL = curr;
                for (int j = p + 1; j <= r; j++) {
                    currR += Get(p + 1, j - 1, a[j] + 1, n);
                    currL -= Get(l, p, a[j] + 1, n);
                }
                currL -= currR;
                currL -= Get(l, p - 1, a[p] + 1, n);
            }   

            if (l < p) {
                costs.insert(currL);
                segs.insert({l, currL});
            }

            if (p < r) {
                costs.insert(currR);
                segs.insert({p + 1, currR});
            }

            // cerr << "curr, currL, currR ---> " << curr << " " << currL << " " << currR << "\n";
            // for (auto c : costs) {
            //     cerr << c << " ";
            // }
            // cerr << "\n\n";

            // if (i == 2) {
            //     cerr << *costs.rbegin();
            //     return 0;
            // }
        }

        cout << "\n";
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Dangerous Syscalls

input:

3
5
4 3 1 1 1
5 4 5 3 1
10
9 7 1 4 7 8 5 7 4 8
21 8 15 5 9 2 4 5 10 6
15
4 8 8 1 12 1 10 14 7 14 2 9 13 10 3
37 19 23 15 7 2 10 15 2 13 4 5 8 7 10

output:


result: