QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#204185#5425. Proposition CompositionUrgantTeamTL 637ms32028kbC++236.9kb2023-10-07 05:09:302023-10-07 05:09:31

Judging History

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

  • [2023-10-07 05:09:31]
  • 评测
  • 测评结果:TL
  • 用时:637ms
  • 内存:32028kb
  • [2023-10-07 05:09:30]
  • 提交

answer

#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<bits/stdc++.h>

using namespace __gnu_pbds;
using namespace std;

typedef tree <
int,
null_type,
less < int >,
rb_tree_tag,
tree_order_statistics_node_update > ordered_set;

typedef long long ll;
int const maxn = 25e4 + 5;
set < int > b[3];
int nxtL[maxn], nxtR[maxn];
int cmp[maxn];
ll sz[maxn], add;
int righ[(1 << 19)], lef[(1 << 19)], n;
ordered_set in[maxn];

inline void upd(int c, int x) {
    add -= sz[c] * (sz[c] - 1) / 2;
    sz[c] += x;
    add += sz[c] * (sz[c] - 1) / 2;
}

void build(int i, int l, int r) {
    if (r - l == 1) righ[i] = nxtR[l], lef[i] = nxtL[l];
    else {
        int m = (r + l) / 2;
        build(2 * i + 1, l, m);
        build(2 * i + 2, m, r);
        righ[i] = max(righ[2 * i + 1], righ[2 * i + 2]);
        lef[i] = min(lef[2 * i + 1], lef[2 * i + 2]);
    }
}

void update(int i, int l, int r, int lq) {
     if (r - l == 1) righ[i] = nxtR[l], lef[i] = nxtL[l];
    else {
        int m = (r + l) / 2;
        if (lq < m) update(2 * i + 1, l, m, lq);
        else update(2 * i + 2, m, r, lq);
        righ[i] = max(righ[2 * i + 1], righ[2 * i + 2]);
        lef[i] = min(lef[2 * i + 1], lef[2 * i + 2]);
    }
}

int getR(int i, int l, int r, int lq, int rq) {
    if (lq >= r || l >= rq || righ[i] < rq) return -1;
    if (r - l == 1) return l;
    int m = (r + l) / 2;
    int res = getR(2 * i + 1, l, m, lq, rq);
    if (res == -1) res = getR(2 * i + 2, m, r, lq, rq);
    return res;
}

int getL(int i, int l, int r, int lq, int rq) {
    if (lq >= r || l >= rq || lef[i] >= lq) return -1;
    if (r - l == 1) return l;
    int m = (r + l) / 2;
    int res = getL(2 * i + 1, l, m, lq, rq);
    if (res == -1) res = getL(2 * i + 2, m, r, lq, rq);
    return res;
}

void func1(int c, int u, int v, int to) {
    auto it = in[c].lower_bound(u);
    vector < int > del;
    int lst = -1;
    if (it != in[c].begin()) {
        it--;
        lst = *it;
        it++;
    }
    while (it != in[c].end()) {
        int now = *it;
        if (now >= v) break;
        in[to].insert(now);
        upd(to, 1);
        upd(c, -1);
        cmp[now] = to;
        it++;
        del.push_back(now);
    }
    for (auto key : del) in[c].erase(key);
    nxtR[del.back()] = del.back();
    nxtL[del[0]] = del[0];
    update(0, 1, n, del[0]);
    update(0, 1, n, del.back());
    if (lst != -1) {
        if (it == in[c].end()) nxtR[lst] = lst;
        else nxtR[lst] = *it;
        update(0, 1, n, lst);
    }
    if (it != in[c].end()) {
        if (lst == -1) {
            nxtL[*it] = *it;
        } else {
            nxtL[*it] = lst;
        }
        update(0, 1, n, *it);
    }
}

void func2(int c, int u, int v, int to) {
    auto it = in[c].begin();
    vector < int > del;
    while (it != in[c].end()) {
        int now = *it;
        if (now >= u) break;
        in[to].insert(now);
        cmp[now] = to;
        upd(to, 1);
        upd(c, -1);
        del.push_back(now);
        it++;
    }
    if (it != in[c].end()) {
        nxtL[*it] = *it;
        update(0, 1, n, *it);
    }
    it = in[c].lower_bound(v);
    assert(it != in[c].begin());
    it--;
    int tmp = *it;
    assert(tmp >= u);
    nxtR[tmp] = tmp;
    update(0, 1, n, tmp);
    it++;
    if (!del.empty()) {
        if (it == in[c].end()) {
            nxtR[del.back()] = del.back();
        } else {
            nxtR[del.back()] = *it;
        }
        update(0, 1, n, del.back());
    }
    if (it != in[c].end()) {
        if (!del.empty()) nxtL[*it] = del.back();
        else nxtL[*it] = *it;
        update(0, 1, n, *it);
    }
    while (it != in[c].end()) {
        int now = *it;
        in[to].insert(now);
        cmp[now] = to;
        upd(to, 1);
        upd(c, -1);
        del.push_back(now);
        it++;
    }
    for (auto key : del) in[c].erase(key);
}

main() {
#ifdef HOME
    freopen("input.txt", "r", stdin);
#endif // HOME
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while (t--) {
        int m, u, v, cur = 2;
        cin >> n >> m;
        for (int j = 0; j < 3; j++) b[j] = {};
        for (int i = 1; i <= n; i++) sz[i] = 0, in[i] = {};
        for (int i = 1; i < n; i++) b[0].insert(i), nxtL[i] = max(1, i - 1), nxtR[i] = min(i + 1, n - 1), cmp[i] = 1, sz[1]++, in[1].insert(i);
        add = sz[1] * (sz[1] - 1) / 2;
        if (n > 1) build(0, 1, n);
        for (int M = 1; M <= m; M++) {
            cin >> u >> v;
            if (u > v) swap(u, v);

            for (int j = 1; j >= 0; j--) {
                auto it = b[j].lower_bound(u);
                vector < int > del;
                while (it != b[j].end() && *it < v) {
                    del.push_back(*it);
                    it++;
                }
                for (auto key : del) {
                    b[j].erase(key);
                    b[j + 1].insert(key);
                }

                while (n > 1 && u < v) {
                    int pos = getR(0, 1, n, u, v);
                    if (pos == -1) break;
                    int L = in[cmp[pos]].order_of_key(u), R = in[cmp[pos]].order_of_key(v);
                    if (R - L <= sz[cmp[pos]] / 2) {
                        func1(cmp[pos], u, v, cur);
                    } else {
                        func2(cmp[pos], u, v, cur);
                    }
                    cur++;
                }

                while (n > 1 && u < v) {
                    int pos = getL(0, 1, n, u, v);
                    if (pos == -1) break;
                    int L = in[cmp[pos]].order_of_key(u), R = in[cmp[pos]].order_of_key(v);
                    if (R - L <= sz[cmp[pos]] / 2) {
                        func1(cmp[pos], u, v, cur);
                    } else {
                        func2(cmp[pos], u, v, cur);
                    }
                    cur++;
                }
            }

            ll ans = 0, cnt = b[0].size();
            ans += (ll)M * cnt;
            ans += b[1].size();
            ans += cnt * (n - 2);
            ans -= cnt * (cnt - 1);
            ans += add;

            for (int i = 1; i < n; i++) {
                int pos = i;
                for (int j = 1; j < i; j++) {
                    if (cmp[i] == cmp[j]) pos = j;
                }
                assert(pos == nxtL[i]);
                pos = i;
                for (int j = i + 1; j < n; j++) {
                    if (cmp[i] == cmp[j]) {
                        pos = j;
                        break;
                    }
                }
                assert(pos == nxtR[i]);

                int sum = 0;
                for (int j = 1; j < n; j++) if (cmp[j] == cmp[i]) sum++;
                assert(sum == sz[cmp[i]]);
            }


            cout << ans << '\n';
        }
    }
    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 4ms
memory: 30864kb

input:

3
4 3
2 4
4 2
3 3
7 3
3 4
1 2
1 7
6 4
1 3
4 6
2 5
3 4

output:

6
5
6
21
24
10
15
12
3
2

result:

ok 10 numbers

Test #2:

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

input:

45540
10 9
10 1
1 10
10 1
1 10
1 10
10 1
1 10
3 3
10 1
10 4
1 2
1 10
3 4
1 10
7 6
7 1
5 6
1 7
6 6
7 1
6 7
9 7
3 3
7 7
5 4
1 1
9 1
9 1
6 5
8 7
1 8
4 4
5 6
1 1
1 8
6 6
4 5
3 3
3 2
3 1
3 3
3 9
3 1
3 3
2 2
3 3
3 1
2 2
1 1
2 3
3 1
10 1
2 1
7 1
1 7
3 8
1 3
1 3
3 3
1 3
2 2
1 3
1 3
3 3
3 6
3 1
1 3
1 3
1 3
1...

output:

45
36
36
36
36
36
36
36
36
45
36
28
21
21
15
10
10
10
6
36
44
50
57
28
21
15
28
28
21
21
15
15
10
3
1
1
3
3
3
3
1
1
1
0
0
45
21
3
1
1
1
1
1
1
1
3
1
1
1
1
1
45
36
36
36
36
36
36
36
3
3
1
0
0
0
0
0
0
3
1
0
0
15
10
10
0
0
0
0
0
0
0
0
28
34
21
6
6
6
6
1
0
0
21
15
15
0
0
0
0
0
0
0
45
53
0
0
0
0
0
0
0
0
1...

result:

ok 249586 numbers

Test #3:

score: 0
Accepted
time: 637ms
memory: 31932kb

input:

2507
86 4
41 41
36 36
31 30
86 1
110 22
1 110
110 1
11 11
110 1
110 1
110 1
1 110
107 106
72 72
106 106
74 74
1 110
110 1
58 58
110 1
110 1
1 110
101 100
110 1
100 100
110 1
8 7
114 180
114 1
114 1
114 1
1 114
1 114
114 1
37 38
49 48
105 106
1 114
90 90
1 114
9 9
114 1
67 68
20 20
114 1
1 114
54 55
...

output:

3655
3740
3823
3570
5995
5886
5886
5886
5886
5886
5886
5778
5778
5778
5778
5778
5778
5778
5778
5778
5778
5671
5671
5671
5671
5565
6441
6328
6328
6328
6328
6328
6216
6105
5995
5995
5995
5995
5995
5995
5886
5886
5886
5886
5778
5671
5671
5565
5565
5460
5460
5460
5460
5460
5356
5253
5253
5253
5151
5151
...

result:

ok 249877 numbers

Test #4:

score: -100
Time Limit Exceeded

input:

3
82425 27858
30801 30802
1 82425
73850 73850
1 82425
65949 65949
82425 1
76026 76025
61936 61936
82425 1
82425 1
82425 1
6504 6504
82425 1
25155 25156
79743 79743
1 82425
69406 69406
29247 29247
18351 18351
23171 23170
29704 29703
82425 1
1 82425
82425 1
74918 74917
22395 22394
893 894
82425 1
391 ...

output:


result: