제출 #1334960

#제출 시각아이디문제언어결과실행 시간메모리
1334960aaaaaaaa게임 (IOI13_game)C++20
63 / 100
1090 ms278740 KiB
#include <bits/stdc++.h>
#include "game.h"
using namespace std;

int r, c;

struct NodeCol {
    NodeCol *left, *right;
    long long value;
    NodeCol() : left(nullptr), right(nullptr), value(0) {}
};

struct NodeRow {
    NodeRow *left, *right;
    NodeCol *col;
    NodeRow() : left(nullptr), right(nullptr), col(nullptr) {}
};

struct Dynamic2DGCD {
    NodeRow* root = new NodeRow();

    // Merge two column nodes
    long long merge_col(NodeCol* a, NodeCol* b) {
        long long val_a = a ? a->value : 0;
        long long val_b = b ? b->value : 0;
        return __gcd(val_a, val_b);
    }

    // Update column tree at column 'col_id'
    void update_col(NodeCol*& node, int start, int end, int col_id, long long val) {
        if (!node) node = new NodeCol();
        if (start == end) {
            node->value = val;
            return;
        }
        int mid = (start + end) / 2;
        if (col_id <= mid) update_col(node->left, start, mid, col_id, val);
        else update_col(node->right, mid + 1, end, col_id, val);
        node->value = merge_col(node->left, node->right);
    }

    // Merge two column trees (used for internal row nodes)
    long long query_col(NodeCol* node, int start, int end, int l, int r) {
        if (!node || start > r || end < l) return 0;
        if (l <= start && end <= r) return node->value;
        int mid = (start + end) / 2;
        return __gcd(query_col(node->left, start, mid, l, r),
                     query_col(node->right, mid + 1, end, l, r));
    }

    // Update row tree at row 'row_id' and column 'col_id'
    void update_row(NodeRow*& node, int start, int end, int row_id, int col_id, long long val) {
        if (!node) node = new NodeRow();
        if (start == end) {
            // Leaf row: update its column tree
            update_col(node->col, 0, c - 1, col_id, val);
            return;
        }
        int mid = (start + end) / 2;
        if (row_id <= mid) update_row(node->left, start, mid, row_id, col_id, val);
        else update_row(node->right, mid + 1, end, row_id, col_id, val);

        // Internal row: merge left and right children for this column
        long long left_val = node->left ? query_col(node->left->col, 0, c - 1, col_id, col_id) : 0;
        long long right_val = node->right ? query_col(node->right->col, 0, c - 1, col_id, col_id) : 0;
        update_col(node->col, 0, c - 1, col_id, __gcd(left_val, right_val));
    }

    // Query row tree for rows [row_l, row_r] and columns [col_l, col_r]
    long long query_row(NodeRow* node, int start, int end, int row_l, int row_r, int col_l, int col_r) {
        if (!node || start > row_r || end < row_l) return 0;
        if (row_l <= start && end <= row_r) return query_col(node->col, 0, c - 1, col_l, col_r);
        int mid = (start + end) / 2;
        return __gcd(query_row(node->left, start, mid, row_l, row_r, col_l, col_r),
                     query_row(node->right, mid + 1, end, row_l, row_r, col_l, col_r));
    }

    // Public API
    void update(int row_id, int col_id, long long val) {
        update_row(root, 0, r - 1, row_id, col_id, val);
    }

    long long query(int row_l, int col_l, int row_r, int col_r) {
        return query_row(root, 0, r - 1, row_l, row_r, col_l, col_r);
    }
} tr;

// API functions
void init(int R, int C) {
    r = R; c = C;
}

void update(int P, int Q, long long K) {
    tr.update(P, Q, K);
}

long long calculate(int P, int Q, int U, int V) {
    return tr.query(P, Q, U, V);
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...