QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#240695#7108. Couleurucup-team2307#AC ✓2800ms57588kbC++144.7kb2023-11-05 17:40:062023-11-05 17:40:07

Judging History

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

  • [2023-11-05 17:40:07]
  • 评测
  • 测评结果:AC
  • 用时:2800ms
  • 内存:57588kb
  • [2023-11-05 17:40:06]
  • 提交

answer

#include<bits/stdc++.h>
using ll = long long;
#define all(x) begin(x), end(x)
using namespace std;

struct Node {
    Node *l = 0, *r = 0;
    int sum = 0;
};

deque<Node> buffer;
Node *copy(Node *v) {
    if(!v) {
        buffer.push_back(Node());
    } else {
        buffer.push_back(Node(*v));
    }
    return &buffer.back();
}

Node *update(Node *root, int l, int r, int p, int v) {
    if(p < l || r < p) return root;
    Node *t = copy(root);
    t->sum += v;
    if(l != r) {
        int m = (l + r) / 2;
        t->l = update(t->l, l, m, p, v);
        t->r = update(t->r, m + 1, r, p, v);
    }
    return t;
}

int query(Node *v, int l, int r, int ql, int qr) {
    if(qr < l || r < ql || !v) return 0;
    if(ql <= l && r <= qr) return v->sum;
    int m = (l + r) / 2;
    return query(v->l, l, m, ql, qr) + query(v->r, m + 1, r, ql, qr);
} 

struct DS {
    int n;
    vector<Node*> roots;
    DS(vector<int> a) : n(a.size()) {
        vector<int> pos(n);
        for(int i = 0; i < n; i++)
            pos[a[i]] = i;
        Node *cur_root = 0;
        for(int i = 0; i < n; i++) {
            roots.push_back(cur_root = update(cur_root, 0, n - 1, pos[i], 1));
        }
    }
    int query(int l, int r, int k) {
        if(k < 0) return 0;
        return ::query(roots[k], 0, n - 1, l, r);
    }
};

int main() {
    cin.tie(0)->sync_with_stdio(0);
    int T;
    cin >> T;
    while(T--) {
        int n;
        cin >> n;
        vector<int> a(n);
        for(auto &i : a) cin >> i;
        
        {
            vector<array<int, 2>> b;
            for(int i = 0; i < n; i++)
                b.push_back({a[i], i});
            sort(all(b));
            for(int i = 0; i < n; i++)
                a[i] = lower_bound(all(b), array<int, 2>{a[i], i}) - b.begin();
        }

        DS ds(a);
        auto inv = [&](int l, int r) {
            ll ans = 0;
            for(int i = l + 1; i < r; i++) {
                ans += ds.query(l, i - 1, a[i]);
                // cout << l << " " << i << " " << a[i] << " " << ds.query(l, i - 1, a[i]) << endl;
            }
            ans = (r - l) * 1ll * (r - l - 1) / 2 - ans;
            return ans;
        };
        auto cross_inv = [&](int l, int r, int tl, int tr) {
            ll ans = 0;
            for(int i = l; i < r; i++) {
                ans += ds.query(tl, tr - 1, a[i]);
            }
            if(r > tr) {
                ll len = r - l;
                ll tlen = tr - tl;
                ans = len * tlen - ans;
            }
            return ans;
        };

        vector<ll> inv_count(n + 1);
        inv_count[n] = inv(0, n);

        set<int> del;
        del.insert(-1);
        del.insert(n);
        multiset<ll> vals;
        ll z = inv_count[n];
        vals.insert(inv_count[n]);
        for(ll t, ti = n; ti--;) {
            cout << z << ' ';//cout << ":";cout.flush();
            cin >> t;
            t ^= z;
            t--;

            auto it = del.insert(t).first;
            int L, R;
            L = *--it; it++;
            R = *++it; it--;

            ll total_inv = inv_count[R];
            vals.erase(vals.find(total_inv));

            ll mid_inv = 0;
            // cout << L + 1 << " " << t << endl;
            mid_inv += (t - L - 1) - ds.query(L + 1, t - 1, a[t]);
            mid_inv += ds.query(t + 1, R - 1, a[t]);
            ll cr_inv, left_inv, right_inv;
            if(R - t < t - L + 1) {
                cr_inv = cross_inv(t + 1, R, L + 1, t);
            } else {
                cr_inv = cross_inv(L + 1, t, t + 1, R);
            }
            total_inv -= mid_inv + cr_inv;
            if(R - t < t - L + 1) {
                right_inv = inv(t + 1, R);
                left_inv = total_inv - right_inv;
            } else {
                left_inv = inv(L + 1, t);
                right_inv = total_inv - left_inv;
            }
            // cout << "data : " << left_inv << " " << right_inv << " " << mid_inv << " " << cr_inv << endl;
            inv_count[R] = right_inv;
            inv_count[t] = left_inv;

            vals.insert(left_inv);
            vals.insert(right_inv);
            z = *vals.rbegin();
        }
        cout << '\n';

        // for(int k = 0; k < n; k++)
        // for(int i = 0; i < n; i++) {
        //     ll val = 0;
        //     for(int j = i; j < n; j++) {
        //         val += a[j] <= k;
        //         ll t = ds.query(i, j, k);
        //         if(val != t) {
        //             cout << k << " : " << i << " " << j << " " << val << " " << t << endl;
        //         }
        //     }
        // }
        buffer.clear();
    }
}

这程序好像有点Bug,我给组数据试试?

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3836kb

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:

7 0 0 0 0 
20 11 7 2 0 0 0 0 0 0 
42 31 21 14 14 4 1 1 1 0 0 0 0 0 0 

result:

ok 3 lines

Test #2:

score: 0
Accepted
time: 2800ms
memory: 57588kb

input:

11116
10
10 5 10 3 6 4 8 5 9 8
31 27 24 11 12 3 0 2 3 1
10
8 2 7 2 8 10 1 10 9 10
6 5 2 13 2 1 0 1 3 1
10
7 10 7 6 1 3 10 6 7 9
21 18 10 1 6 5 4 8 9 10
10
2 10 4 8 8 5 7 2 6 7
20 10 9 1 15 0 4 2 9 7
10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
10
1 2 3 4 5 6 7 8 9 10
6 3 5 2 7 10 9 1 4 8
10
1 10 1 3...

output:

21 18 16 12 10 6 4 1 1 0 
12 12 10 10 4 4 4 2 1 0 
20 16 9 5 3 3 3 0 0 0 
22 14 8 8 5 5 2 1 1 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
19 12 7 4 4 2 2 1 0 0 
20 18 8 3 1 1 0 0 0 0 
45 21 21 10 3 3 3 0 0 0 
17 11 8 2 1 1 1 0 0 0 
13 4 1 0 0 0 0 0 0 0 
29 27 22 15 9 7 4 3 1 0 
26 16 9 2 1 1 1 1 1 ...

result:

ok 11116 lines

Extra Test:

score: 0
Extra Test Passed