QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#503349#8523. Puzzle IIucup-team4435#WA 0ms3624kbC++204.6kb2024-08-03 17:50:232024-08-03 17:50:23

Judging History

This is the latest submission verdict.

  • [2024-08-03 17:50:23]
  • Judged
  • Verdict: WA
  • Time: 0ms
  • Memory: 3624kb
  • [2024-08-03 17:50:23]
  • Submitted

answer

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;

#define all(a) begin(a), end(a)
#define len(a) int((a).size())

#ifdef LOCAL
    #include "debug.h"
#else
    #define dbg(...)
    #define dprint(...)
    #define debug if constexpr (false)
    #define draw_tree(...)
    #define draw_array(...)
#endif // LOCAL

std::mt19937 __rng__(std::chrono::steady_clock::now().time_since_epoch().count());

struct node {
    int val, sum;

    int left, right, sz, y;

    node(int x) : val(x), sum(x), left(-1), right(-1), sz(1), y(__rng__()) {}
};

std::vector<node> tree;

int sum(int v) {
    return (v == -1 ? 0 : tree[v].sum);
}

int size(int v) {
    return (v == -1 ? 0 : tree[v].sz);
}

void relax(int v) {
    tree[v].sz = 1 + size(tree[v].left) + size(tree[v].right);
    tree[v].sum = tree[v].val + sum(tree[v].left) + sum(tree[v].right);
}

int new_node(int x) {
    int id = int(tree.size());
    tree.push_back(node(x));
    return id;
}

std::pair<int, int> split_by_size(int v, int n) {
    if (v == -1)
        return {v, v};

    if (size(tree[v].left) + 1 <= n) {
        auto cur = split_by_size(tree[v].right, n - size(tree[v].left) - 1);
        tree[v].right = cur.first;
        relax(v);
        return {v, cur.second};
    } else {
        auto cur = split_by_size(tree[v].left, n);
        tree[v].left = cur.second;
        relax(v);
        return {cur.first, v};
    }
}

int merge(int left, int right) {
    if (left == -1)
        return right;

    if (right == -1)
        return left;

    if (tree[left].y > tree[right].y) {
        tree[left].right = merge(tree[left].right, right);
        relax(left);
        return left;
    } else {
        tree[right].left = merge(left, tree[right].left);
        relax(right);
        return right;
    }
}

int pos(int v, int x) {
    assert(v != -1);

    int cnt_left = (x == 1 ? sum(tree[v].left) : size(tree[v].left) - sum(tree[v].left));
    if (cnt_left > 0) {
        return pos(tree[v].left, x);
    }

    if (tree[v].val == x) {
        return size(tree[v].left);
    }

    return size(tree[v].left) + 1 + pos(tree[v].right, x);
}

void print(int v) {
    if (v == -1) {
        return;
    }
    print(tree[v].left);
    cerr << tree[v].val << ' ';
    print(tree[v].right);
}

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int n, k;
    string a, b;
    cin >> n >> k >> a >> b;

    if (count(all(a), 'C') * 2 > n) {
        for (auto &c : a) {
            c ^= 'C' ^ 'B';
        }
        for (auto &c : b) {
            c ^= 'C' ^ 'B';
        }
    }

    int ta = -1, tb = -1;
    for (int i = 0; i < n; i++) {
        int na = new_node(a[i] == 'C');
        int nb = new_node(b[i] == 'C');
        ta = merge(ta, na);
        tb = merge(tb, nb);
    }

    auto debug_print = [&]() {
        debug {
            dprint("state");
            cerr << "ta: ";
            print(ta);
            cerr << endl;
            cerr << "tb: ";
            print(tb);
            cerr << endl;
        }
    };

    dprint("init");
    debug_print();

    vector<pair<int, int>> ops;

    auto op = [&](int i, int j) {
        ops.emplace_back(i, j);

        auto split_tree = [&](int t, int pos) -> array<int, 3> {
            if (pos + k <= n) {
                auto [l, mr] = split_by_size(t, pos);
                auto [m, r] = split_by_size(mr, k);
                return {l, m, r};
            }

            int part = pos + k - n;
            auto [m2, lm] = split_by_size(t, part);
            auto [l, m] = split_by_size(lm, pos - part);
            return {l, merge(m, m2), -1};
        };

        auto [l1, m1, r1] = split_tree(ta, i);
        auto [l2, m2, r2] = split_tree(tb, j);

        auto merge_back = [&](int l, int m, int r, int pos) {
            if (pos + k <= n) {
                return merge(l, merge(m, r));
            }

            int part = pos + k - n;
            auto [m1, m2] = split_by_size(m, k - part);
            return merge(m2, merge(l, m1));
        };

        ta = merge_back(l1, m2, r1, i);
        tb = merge_back(l2, m1, r2, j);

        dprint("\nop", i, j);
        debug_print();
    };

    while (sum(ta) != 0) {
        int i = pos(ta, 1);
        int j = pos(tb, 0);
        int pos = (i + n - k) % n;
        op(pos, j);
        op((pos + 1) % n, j);
    }

    assert(len(ops) <= n);
    for (auto [i, j] : ops) {
        cout << i + 1 << ' ' << j + 1 << '\n';
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

6 3
BCCBCC
BBCBBC

output:

4 3
5 3
2 6
3 6

result:

wrong output format Unexpected end of file - int32 expected