QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#133175#6630. Triangle CollectionCyanmond0 13ms3684kbC++147.0kb2023-08-01 16:55:002023-08-01 16:55:01

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-08-01 16:55:01]
  • 评测
  • 测评结果:0
  • 用时:13ms
  • 内存:3684kb
  • [2023-08-01 16:55:00]
  • 提交

answer

#include <bits/stdc++.h>
// #include "atcoder/modint"

using i64 = long long;
// using Fp = atcoder::modint998244353;

int op(int a, int b) {
    return std::min(a, b);
}
int e() {
    return 1 << 30;
}
int mapping(int a, int b) {
    return a + b;
}
int composition(int a, int b) {
    return a + b;
}
int id() {
    return 0;
}

class LazySegTree {
    int n, size, log;
    std::vector<int> data, lazy;

    void upd(int i) {
        data[i] = op(data[2 * i], data[2 * i + 1]);
    }
    void app(int k, int f) {
        data[k] = mapping(f, data[k]);
        if (k < size) lazy[k] = composition(f, lazy[k]);
    }
    void push(int k) {
        app(2 * k, lazy[k]);
        app(2 * k + 1, lazy[k]);
        lazy[k] = id();
    }

    public:
    LazySegTree(int n_) : n(n_) {
        log = 1;
        while ((1 << log) < n) ++log;
        size = 1 << log;
        data.assign(2 * size, e());
        lazy.assign(size, id());
    }

    int fold(int l, int r) {
        if (l == r) return e();
        l += size;
        r += size;
        for (int d = log; d >= 1; --d) {
            if (((l >> d) << d) != l) push(l >> d);
            if (((r >> d) << d) != r) push((r - 1) >> d);
        }

        int ret = 1 << 30;
        while (l < r) {
            if (l % 2 == 1) ret = op(ret, data[l++]);
            if (r % 2 == 1) ret = op(ret, data[--r]);
            l /= 2;
            r /= 2;
        }
        return ret;
    }

    void apply(int l, int r, int f) {
        l += size;
        r += size;
        for (int d = log; d >= 1; --d) {
            if (((l >> d) << d) != l) push(l >> d);
            if (((r >> d) << d) != r) push((r - 1) >> d);
        }

        int l2 = l, r2 = r;
        while (l < r) {
            if (l % 2 == 1) app(l++, f);
            if (r % 2 == 1) app(--r, f);
            l /= 2;
            r /= 2;
        }
        l = l2;
        r = r2;

        for (int d = 1; d <= log; ++d) {
            if (((l >> d) << d) != l) upd(l >> d);
            if (((r >> d) << d) != r) upd((r - 1) >> d);
        }
    }

    int get(int i) {
        return fold(i, i + 1);
    }

    void set(int i, int v) {
        apply(i, i + 1, v - get(i));
    }
};

int main() {
    int N, Q;
    std::cin >> N >> Q;
    std::vector<i64> C(N + 1);
    for (int i = 1; i <= N; ++i) {
        std::cin >> C[i];
    }

    std::vector<i64> L(Q), D(Q);
    for (int i = 0; i < Q; ++i) {
        std::cin >> L[i] >> D[i];
    }

    /*
    if (N <= 2000 and Q <= 2000) {
        for (int q = 0; q < Q; ++q) {
            C[L[q]] += D[q];

            std::vector<int> O;
            for (int i = 1; i <= N; ++i) {
                if (C[i] % 2 == 1) {
                    O.push_back(i);
                }
            }
            auto D = C;
            for (auto &e : D) e = e / 2;

            int i = N;
            std::reverse(O.begin(), O.end());
            i64 ans = 0;
            for (const auto s : O) {
                while (i != 0 and D[i] == 0) --i;
                const int l = s / 2 + 1;
                if (i >= l) {
                    --D[i];
                    ++ans;
                }
            }
            i64 sum = 0;
            for (auto e : D) sum += e;
            ans += sum * 2 / 3;
            std::cout << ans << std::endl;
        }
        return 0;
    }
    */
    // subtask 3
    std::set<int> a, b, x, y;
    for (int i = 1; i <= N; ++i) {
        if (C[i] == 1) a.insert(i);
        if (C[i] == 2) x.insert(i);
    }
    int p = 0;

    LazySegTree seg(N + 1);
    for (int i = 0; i <= N; ++i) seg.set(i, 0);
    while (true) {
        if (a.empty() or x.empty()) break;
        const int u = *a.begin(), v = *x.rbegin();
        seg.apply((u / 2) + 1, N + 1, 1);
        seg.apply(v, N + 1, -1);
        if (seg.fold(0, N + 1) < 0) {
            seg.apply((u / 2) + 1, N + 1, -1);
            seg.apply(v, N + 1, 1);
            break;
        } else {
            ++p;
            a.erase(u);
            x.erase(v);
            b.insert(u);
            y.insert(v);
        }
    }

    /*
    for (const auto e : a) std::cerr << e << ' ';
    std::cerr << std::endl;
    for (const auto e : b) std::cerr << e << ' ';
    std::cerr << std::endl;
    for (const auto e : x) std::cerr << e << ' ';
    std::cerr << std::endl;
    for (const auto e : y) std::cerr << e << ' ';
    std::cerr << std::endl;
    */

    auto upd = [&]() {
        while (seg.fold(0, N + 1) < 0) {
            const int u = *b.rbegin(), v = *y.begin();
            seg.apply((u / 2) + 1, N + 1, -1);
            seg.apply(v, N + 1, 1);
            --p;
            b.erase(u);
            y.erase(v);
            a.insert(u);
            x.insert(v);
        }
        while (true) {
            if (a.empty() or x.empty()) break;
            const int u = *a.begin(), v = *x.rbegin();
            seg.apply((u / 2) + 1, N + 1, 1);
            seg.apply(v, N + 1, -1);
            if (seg.fold(0, N + 1) < 0) {
                seg.apply((u / 2) + 1, N + 1, -1);
                seg.apply(v, N + 1, 1);
                break;
            } else {
                ++p;
                a.erase(u);
                x.erase(v);
                b.insert(u);
                y.insert(v);
            }
        }
    };

    auto erase = [&](int v) {
        if (a.find(v) != a.end()) {
            a.erase(v);
        }
        if (b.find(v) != b.end()) {
            seg.apply((v / 2) + 1, N + 1, -1);
            const int o = *y.begin();
            seg.apply(o, N + 1, 1);
            y.erase(o);
            x.insert(o);
            b.erase(v);
            --p;
        }
        if (x.find(v) != x.end()) {
            x.erase(v);
        }
        if (y.find(v) != y.end()) {
            seg.apply(v, N + 1, 1);
            const int o = *b.rbegin();
            seg.apply((o / 2) + 1, N + 1, -1);
            b.erase(o);
            a.insert(o);
            y.erase(v);
            --p;
        }
    };

    auto rollback = [&]() {
        if (b.empty()) return;
        const int u = *b.rbegin(), v = *y.begin();
        seg.apply((u / 2) + 1, N + 1, -1);
        seg.apply(v, N + 1, 1);
        --p;
        b.erase(u);
        y.erase(v);
        a.insert(u);
        x.insert(v);
    };

    auto adda = [&](int v) {
        a.insert(v);
        rollback();
        upd();
    };

    auto addx = [&](int v) {
        x.insert(v);
        rollback();
        upd();
    };

    for (int q = 0; q < Q; ++q) {
        erase(L[q]);
        C[L[q]] += D[q];
        if (C[L[q]] == 1) adda(L[q]);
        else if (C[L[q]] == 2) addx(L[q]);
        upd();
        std::cout << p + x.size() * 2 / 3 << std::endl;
    }

    /*
    if (std::all_of(D.begin(), D.end(), [&](int v) {
        return std::abs(v) <= 1;
    })) {
        // subtask 4

    } else {
        // subtask 3

    }
    */
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Wrong Answer

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3520kb

input:

1 23
1485
1 -12
1 -30
1 -20
1 6
1 24
1 5
1 31
1 14
1 -34
1 -22
1 -45
1 37
1 46
1 9
1 22
1 -9
1 9
1 -46
1 -47
1 39
1 36
1 -36
1 50

output:

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

result:

wrong answer 1st numbers differ - expected: '491', found: '0'

Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Time Limit Exceeded

Test #28:

score: 5
Accepted
time: 6ms
memory: 3660kb

input:

1999 2000
1 1 1 1 0 2 0 2 1 0 2 1 2 2 2 1 2 0 0 1 2 2 0 1 0 1 0 2 0 0 2 1 1 1 1 0 1 2 1 2 1 1 1 1 1 0 2 2 0 2 1 1 2 0 0 2 0 0 2 1 2 0 0 1 1 2 0 2 2 2 1 2 0 2 1 2 0 1 2 2 2 1 1 2 1 1 1 1 0 0 1 1 0 1 2 1 0 0 2 0 2 2 2 0 1 1 2 0 0 1 0 0 2 1 2 1 2 0 1 1 2 2 0 0 1 2 2 1 2 1 2 2 2 0 0 1 1 2 1 1 2 2 2 2 2 ...

output:

660
660
660
661
661
661
661
660
660
660
660
661
662
662
663
663
662
661
662
662
661
660
661
660
660
660
661
661
661
661
662
661
661
660
661
660
659
658
658
659
659
658
659
660
660
660
660
660
660
659
659
659
659
659
659
659
659
660
659
658
658
658
658
657
657
657
658
657
656
657
657
657
656
656
655
...

result:

ok 2000 numbers

Test #29:

score: 0
Accepted
time: 13ms
memory: 3684kb

input:

2000 2000
0 1 1 0 0 0 0 1 1 2 0 2 1 2 0 0 0 0 1 0 0 1 2 0 1 1 0 0 1 2 1 1 2 2 2 1 1 2 0 2 2 0 1 0 1 2 2 0 2 0 0 2 0 1 2 2 0 1 0 1 0 1 0 2 0 2 1 2 1 1 0 1 2 0 1 1 1 2 0 2 1 1 2 1 2 0 1 0 0 0 0 2 2 0 2 2 0 2 2 1 0 1 2 1 0 2 0 1 1 2 2 0 0 0 0 2 0 2 2 1 1 1 2 2 0 1 2 0 2 1 0 1 1 2 2 2 0 0 0 0 1 0 0 2 1 ...

output:

679
679
679
679
679
679
679
678
679
678
678
678
679
678
679
678
678
678
678
678
677
678
677
678
678
678
679
678
678
678
678
678
677
677
677
678
677
678
678
678
678
678
678
678
679
678
679
679
679
680
680
680
680
680
680
679
678
677
676
677
676
676
677
676
675
674
674
674
674
674
674
673
673
672
672
...

result:

ok 2000 numbers

Test #30:

score: -5
Time Limit Exceeded

input:

10 200000
1 2 2 2 2 1 0 2 2 2
10 -1
3 0
5 0
10 -1
10 0
3 0
5 0
7 1
9 -2
10 2
2 -2
6 -1
6 0
8 -1
4 -2
2 0
5 -1
8 1
1 1
4 1
1 -2
3 0
4 1
9 0
9 0
6 1
7 -1
4 -2
2 1
6 0
8 0
3 0
5 -1
10 -1
5 2
9 1
1 0
6 -1
2 0
9 1
2 1
4 2
5 -2
7 1
3 0
1 2
9 0
5 1
1 -1
6 2
6 -2
9 -1
8 -2
6 1
2 -2
1 -1
10 -1
2 0
8 2
6 -1
2...

output:

5
5
5
4
4
4
4
5
4
5
4
4
4
3
3
3
2
3
3
3
3
3
3
3
3
3
3
2
3
3
3
3
2
2
3
3
3
3
3
3
3
4
3
4
4
4
4
5
4
5
4
4
3
3
2
2
2
2
3
3
3
3
2
3
2
2
2
2
2
2
2
3
3
3
2
2
2
1
1
1
1
0
0
0
0
0
0
0
1
1
1
1
2
2
2
2
2
2
2
2
2
2
1
1
1
0
0
0
0
0
0
0
0
1
1
1
1
2
2
2
2
2
3
3
3
2
2
3
3
2
2
2
2
2
2
2
2
2
2
2
2
3
3
3
4
4
4
3
3
4
...

result:


Subtask #4:

score: 0
Wrong Answer

Test #35:

score: 0
Wrong Answer
time: 7ms
memory: 3632kb

input:

2000 1999
0 1 0 3 0 1 0 0 0 0 0 0 0 2 0 0 0 0 3 1 1 0 2 0 0 3 0 0 0 0 0 4 0 0 1 0 1 0 0 0 0 1 2 1 0 0 0 0 7 0 1 3 1 0 1 1 0 3 2 1 0 1 1 3 3 1 0 2 0 0 0 0 0 0 0 0 1 0 0 0 2 0 0 0 0 0 1 2 3 0 1 0 3 3 0 0 0 0 1 0 1 2 0 0 2 2 0 1 2 1 2 0 0 0 1 1 0 1 2 0 0 0 0 2 0 5 0 0 0 0 0 1 0 0 2 0 1 2 0 1 0 0 0 2 0 ...

output:

238
238
238
238
239
239
239
239
239
240
240
240
240
241
241
240
239
239
239
240
241
240
239
239
238
238
237
237
237
237
238
238
239
239
239
239
239
239
239
239
238
238
237
237
237
237
238
238
239
239
239
239
239
239
239
239
239
239
239
239
239
239
239
240
241
242
242
242
242
242
243
243
243
243
243
...

result:

wrong answer 1st numbers differ - expected: '666', found: '238'

Subtask #5:

score: 0
Skipped

Dependency #1:

0%