Submission #1352307

#TimeUsernameProblemLanguageResultExecution timeMemory
1352307tickcrossyMigrations (IOI25_migrations)C++20
30 / 100
23 ms972 KiB
#include <vector>
#include <algorithm>

using namespace std;

// 倍增 LCA 及树深维护,N 最大 10000
static int depth[10005];
static int up[14][10005];

// 在线直径和内部状态维护
static int U_node = 0, V_node = 0, D_tree = 0;
static int max_dist_0 = 0, furthest_from_0 = 0;
static int protocol = 0;
static long long B_star = 0;
static long long id_val = 0;
static int bit_idx = 0;

// O(log N) 查询两点距离
int get_lca(int u, int v) {
    if (depth[u] < depth[v]) swap(u, v);
    int diff = depth[u] - depth[v];
    for (int j = 0; j < 14; j++) {
        if ((diff >> j) & 1) u = up[j][u];
    }
    if (u == v) return u;
    for (int j = 13; j >= 0; j--) {
        if (up[j][u] != up[j][v]) {
            u = up[j][u];
            v = up[j][v];
        }
    }
    return up[0][u];
}

int get_dist(int u, int v) {
    return depth[u] + depth[v] - 2 * depth[get_lca(u, v)];
}

// ============== 研究团队函数 ==============
int send_message(int N, int i, int Pi) {
    // 首次调用,复位所有内部静态状态
    if (i == 1) { 
        depth[0] = 0;
        for (int j = 0; j < 14; j++) up[j][0] = 0;
        U_node = 0; V_node = 0; D_tree = 0;
        max_dist_0 = 0; furthest_from_0 = 0;
        protocol = 0; B_star = 0; id_val = 0; bit_idx = 0;
    }

    // 倍增表更新
    depth[i] = depth[Pi] + 1;
    up[0][i] = Pi;
    for (int j = 1; j < 14; j++) {
        up[j][i] = up[j-1][up[j-1][i]];
    }

    int dist0 = get_dist(i, 0);
    bool dist0_inc = false;
    if (dist0 > max_dist_0) {
        dist0_inc = true;
        max_dist_0 = dist0;
        furthest_from_0 = i;
    }

    int dU = get_dist(i, U_node);
    int dV = get_dist(i, V_node);
    bool increased = false;
    int replaced = 0; 
    int max_d = max(dU, dV);
    
    // 若当步节点使得树直径延长,立刻进行贪心更迭
    if (max_d > D_tree) {
        increased = true;
        D_tree = max_d;
        if (dU > dV) {
            replaced = 1; // 距离 U 较远,意味着新节点取代了原始 V
            V_node = i;
        } else {
            replaced = 2; // 距离 V 较远,意味着新节点取代了原始 U
            U_node = i;
        }
    }

    // N-50 步时,判定接下来采取哪个协议传输(同时规避恶意长链)
    if (i == N - 50) { 
        if (U_node == 0 || V_node == 0) {
            protocol = 1; 
        } else {
            protocol = 2; 
            // 注意:绝不可重排序 U_node 与 V_node 以免与后期的抢占指令冲突混淆
            id_val = U_node * 10000LL + V_node;
            bit_idx = 0;
        }
    }

    if (i == N - 15 && protocol == 1) {
        B_star = furthest_from_0;
        bit_idx = 0;
    }

    // ====== 发送消息:严格限制 Z <= 4 ======

    // 协议 2:50 步防连击高稳缓冲法
    if (protocol == 2 && i >= N - 50) {
        if (increased) {
            return replaced == 1 ? 3 : 4; 
        } else {
            if (bit_idx < 27) {
                long long b = (id_val >> bit_idx) & 1;
                bit_idx++;
                return b + 1; 
            }
        }
    }

    // 协议 1:Subtask 1 特供轻量级编码法
    if (protocol == 1 && i >= N - 14) {
        if (dist0_inc) return 3; // 信号 3 意为:覆盖成为最新的远端点
        if (bit_idx < 14) {
            int d_i = (B_star >> bit_idx) & 1;
            bit_idx++;
            return d_i + 1;
        }
    }

    return 0; // 静默隐身状态避免提前招惹评测机
}

// ============== 博物馆函数 ==============
std::pair<int, int> longest_path(std::vector<int> S) {
    int N = S.size();
    bool is_p2 = false;
    
    // 辨别协议:Protocol 2 从 N-50 就开始发了,Protocol 1 是 N-14 才开始
    for (int i = N - 50; i < N - 14; i++) {
        if (S[i] > 0) is_p2 = true;
    }
    
    if (is_p2) {
        long long id = 0;
        int b_idx = 0;
        int final_U = -1, final_V = -1;
        for (int i = N - 50; i < N; i++) {
            if (S[i] == 3) {
                final_V = i;
            } else if (S[i] == 4) {
                final_U = i;
            } else if (S[i] == 1 || S[i] == 2) {
                if (b_idx < 27) {
                    id |= ((long long)(S[i] - 1) << b_idx);
                    b_idx++;
                }
            }
        }
        int initial_U = id / 10000;
        int initial_V = id % 10000;
        if (final_U == -1) final_U = initial_U;
        if (final_V == -1) final_V = initial_V;
        return {final_U, final_V};
    } else {
        int V = 0;
        int last_update = -1;
        int b_idx = 0;
        for (int i = N - 14; i < N; i++) {
            if (S[i] == 3) {
                last_update = i;
            } else if (S[i] == 1 || S[i] == 2) {
                if (b_idx < 14) {
                    V |= ((S[i] - 1) << b_idx);
                    b_idx++;
                }
            }
        }
        if (last_update != -1) V = last_update;
        return {0, V};
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...