提交记录 14388


用户 题目 状态 得分 用时 内存 语言 代码长度
dram router32. 测测你的路由器 Accepted 100 496.807 ms 56712 KB C++ 2.46 KB
提交时间 评测时间
2020-09-26 18:39:03 2020-09-26 18:39:11
#include "router.h"

#include <stdint.h>
#include <netinet/in.h>

#include <new>
#include <unordered_set>
#include <algorithm>

inline uint32_t mask(unsigned char len) {
    return len == 0 ? 0 : ((~0) << (32 - len));
}

struct Node {
    uint32_t prefix;
    unsigned char len;
    bool valid;
    uint32_t nexthop;
    Node *next[2];
} *pool = new Node[2 << 20];

inline Node *alloc() {
    return pool ++;
}

Node *root = 0;

Node **trie_find(uint32_t addr, unsigned char lenlim = 32, bool insert = false) {
    Node **cur = &root, **val = 0;
    while (*cur) {
        if ((addr & mask((*cur)->len)) != (*cur)->prefix) break;
        if ((*cur)->valid) val = cur;
        if ((*cur)->len >= lenlim) break;

        size_t b = (addr & (1 << (31 - (*cur)->len))) ? 1 : 0;
        cur = &((*cur)->next[b]);
    }
    return insert ? cur : val;
}

void trie_add(uint32_t prefix, unsigned char len, uint32_t nexthop) {
    Node **f = trie_find(prefix, len, true);

    if (*f == 0) {
        *f = new(alloc()) Node {
            .prefix = prefix,
            .len = len,
            .valid = 1,
            .nexthop = nexthop,
            .next { 0, 0 }
        };
    } else {
        uint32_t pattern = (prefix ^ (*f)->prefix) | ~mask(std::min((*f)->len, len));
        unsigned char common = pattern == 0 ? 32 : __builtin_clz(pattern);

        size_t pb = (pattern & (1 << (31 - common))) ? 1 : 0;

        if (common == (*f)->len) {
            (*f)->valid = true;
            (*f)->nexthop = nexthop;
        } else {
            Node *new_node = new(alloc()) Node {
                .prefix = prefix & mask(common),
                .len = common,
                .valid = 0,
                .next { 0, 0 }
            };
            new_node->next[!pb] = *f;
            *f = new_node;
            if (common == len) {
                new_node->valid = true;
                new_node->nexthop = nexthop;
            } else {
                new_node->next[pb] = new(alloc()) Node {
                    .prefix = prefix,
                    .len = len,
                    .valid = 1,
                    .nexthop = nexthop,
                    .next { 0, 0 }
                };
            }
        }
    }
}

void init(int n, int q, const RoutingTableEntry *a) {
	for (size_t i = 0; i < (size_t) n; i ++) {
        trie_add(ntohl(a[i].addr), a[i].len, a[i].nexthop);
    }
}

unsigned query(unsigned addr) {
    Node **node = trie_find(ntohl(addr));
    if (! node || ! *node) return 0;
    return (*node)->nexthop;
}

CompilationN/AN/ACompile OKScore: N/A

Testcase #112.54 us28 KBAcceptedScore: 25

Testcase #257.395 ms55 MB + 392 KBAcceptedScore: 25

Testcase #3277.202 ms55 MB + 392 KBAcceptedScore: 25

Testcase #4496.807 ms55 MB + 392 KBAcceptedScore: 25


Judge Duck Online | 评测鸭在线
Server Time: 2024-04-25 15:20:51 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用