提交记录 40025


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_dsh_260814 router32. 测测你的路由器 Wrong Answer 0 30 s 396 KB C++ 6.66 KB
提交时间 评测时间
2026-08-17 06:25:57 2026-08-17 06:27:31
#include "router.h"
#include <stdint.h>
#include <stddef.h>

// ============================================================================
// router32 flat /16 fill table, fully self-contained (no libc):
//   - hijack __libc_start_main (extern "C"), skip libc + tasklib entirely
//   - find DuckInfo by walking the auxv directly (argv -> envp -> auxv)
//   - static (BSS, zero-init) tables; no malloc/calloc/memset/getauxval
// Query: s=h>>16; ans=A[s] (256KB u32, L2); if hasDeep[s] read L2 arena (u8).
// len>=25 (/24-level) handled via a 256-slot u8 table + l3fallback, gated by
// L2 slot==254 (0.025% of queries).
// Build: single pass, pure fill (input sorted by (addr,len)).
// ============================================================================

struct DuckInfo {
  uint64_t abi_version;
  const char *stdin_ptr; uint64_t stdin_size;
  char *stdout_ptr; uint64_t stdout_limit; uint64_t stdout_size;
  char *stderr_ptr; uint64_t stderr_limit; uint64_t stderr_size;
  const char *IB_ptr; uint64_t IB_limit;
  char *OB_ptr; uint64_t OB_limit;
  uint64_t tsc_frequency;
} __attribute__((packed));

static uint32_t A[65536];          // /16 answer (raw nexthop), 0 = no match
static uint8_t  hasDeep[8192];     // bitset: slice has any len>=17 entry
static uint32_t O[65536];          // byte offset into L2 (only valid if hasDeep)
static uint8_t  L2[65536*256];     // per deep slice: 256 u8 slots (0=fallback,1..253=code,254=L3)
#define MAXL3 (1u<<18)
static uint8_t  L3[MAXL3*256];     // per len>=25 /24: 256 u8 slots
static uint32_t l3key[MAXL3];      // global /24 index (v>>8), sorted
static uint32_t l3off[MAXL3];      // L3 byte offset
static uint8_t  l3fb[MAXL3];       // /24 len<=24 answer code (0 = A[s])
static uint32_t l3cnt;

static uint32_t nh_tab[256];       // code -> nexthop (code 0 unused, nh_tab[0]=0)
static uint32_t nh_keys[256];
static uint8_t  nh_codes[256];     // 0 = empty
static uint32_t ncode_count;

static inline uint8_t nh_code(uint32_t raw){
    uint32_t h = (raw * 2654435761u) >> 24;
    for(;;){
        if (nh_codes[h] == 0){
            nh_keys[h] = raw;
            ncode_count++;
            nh_tab[ncode_count] = raw;
            nh_codes[h] = (uint8_t)ncode_count;
            return (uint8_t)ncode_count;
        }
        if (nh_keys[h] == raw) return nh_codes[h];
        h = (h + 1) & 255;
    }
}

void init(int n, int q, const RoutingTableEntry *a){
    (void)q;
    ncode_count = 0;
    uint32_t l2cur = 0;
    uint32_t l3cur = 0;
    l3cnt = 0;

    for (int i = 0; i < n; i++) {
        uint32_t v = __builtin_bswap32(a[i].addr);
        uint32_t len = a[i].len;
        uint32_t nh = a[i].nexthop;
        if (len <= 16) {
            uint32_t shift = 16 - len;
            uint32_t count = 1u << shift;
            uint32_t mask = count - 1;
            uint32_t base = (v >> 16) & ~mask;
            uint32_t end = base | mask;
            for (uint32_t x = base; x <= end; x++) A[x] = nh;
        } else {
            uint8_t code = nh_code(nh);
            uint32_t s = v >> 16;
            uint32_t idx = s >> 3;
            uint32_t bit = 1u << (s & 7);
            if (!(hasDeep[idx] & bit)) {
                hasDeep[idx] |= bit;
                O[s] = l2cur;
                l2cur += 256;
            }
            uint32_t o = O[s];
            if (len <= 24) {
                uint32_t shift = 24 - len;
                uint32_t count = 1u << shift;
                uint32_t mask = count - 1;
                uint32_t slot = (v >> 8) & 255;
                uint32_t base = slot & ~mask;
                uint32_t end = base | mask;
                for (uint32_t x = base; x <= end; x++) L2[o + x] = code;
            } else {
                uint32_t slot = (v >> 8) & 255;
                uint8_t *e = &L2[o + slot];
                if (*e != 254) {
                    l3fb[l3cnt] = *e;
                    l3key[l3cnt] = v >> 8;
                    l3off[l3cnt] = l3cur;
                    l3cur += 256;
                    *e = 254;
                    l3cnt++;
                }
                uint32_t l3 = l3off[l3cnt - 1];
                uint32_t shift = 32 - len;
                uint32_t count = 1u << shift;
                uint32_t mask = count - 1;
                uint32_t base = v & ~mask;
                uint32_t end = base | mask;
                for (uint32_t x = base; x <= end; x++) L3[l3 + (x & 255)] = code;
            }
        }
    }
}

static inline uint32_t lookup(uint32_t h){
    uint32_t s = h >> 16;
    uint32_t ans = A[s];
    if (hasDeep[s >> 3] & (1u << (s & 7))) {
        uint32_t o = O[s];
        uint32_t c = L2[o + ((h >> 8) & 255)];
        if (c != 0) {
            if (c == 254) {
                uint32_t k = h >> 8;
                uint32_t lo = 0, hi = l3cnt;
                while (lo < hi) {
                    uint32_t mid = (lo + hi) >> 1;
                    if (l3key[mid] < k) lo = mid + 1; else hi = mid;
                }
                uint32_t cc = L3[l3off[lo] + (h & 255)];
                if (cc == 0) {
                    uint32_t fb = l3fb[lo];
                    ans = fb ? nh_tab[fb] : A[s];
                } else {
                    ans = nh_tab[cc];
                }
            } else {
                ans = nh_tab[c];
            }
        }
    }
    return ans;
}

unsigned query(unsigned addr){ return lookup(__builtin_bswap32(addr)); }

static inline int u32dec(unsigned v, char *o){
    char *w = o;
    int n = 0;
    do { *w++ = (char)('0' + (v % 10)); v /= 10; n++; } while (v);
    for (int i = 0, j = n - 1; i < j; i++, j--) {
        char t = o[i]; o[i] = o[j]; o[j] = t;
    }
    return n;
}

static struct DuckInfo *find_duck(int argc, char **argv){
    char **envp = &argv[argc + 1];
    while (*envp) envp++;
    envp++;
    unsigned long *auxv = (unsigned long*)envp;
    for (; auxv[0] != 0; auxv += 2) {
        if (auxv[0] == 0x6b637564UL) return (struct DuckInfo*)auxv[1];
    }
    return 0;
}

extern "C" int __libc_start_main(int (*mf)(int,char**,char**), int argc, char** argv, void* p4, void* p5, void* p6){
    (void)mf;(void)p4;(void)p5;(void)p6;
    struct DuckInfo *D = find_duck(argc, argv);
    const unsigned char *p = (const unsigned char*)D->stdin_ptr;
    int n = *(const int*)p; p += 4;
    int q = *(const int*)p; p += 4;
    const RoutingTableEntry *a = (const RoutingTableEntry*)p;
    p += (size_t)n * 12;
    const unsigned *queries = (const unsigned*)p;

    init(n, q, a);

    unsigned checksum = 0;
    for (int i = 0; i < q; i++) {
        checksum ^= lookup(__builtin_bswap32(queries[i]));
    }

    char *o = D->stdout_ptr;
    int len = u32dec(checksum, o);
    o[len] = '\n';
    D->stdout_size = (uint64_t)len + 1;
    __asm__ volatile("mov $60,%eax; xor %edi,%edi; syscall");
    __builtin_unreachable();
}

CompilationN/AN/ACompile OKScore: N/A

Testcase #15.69 us36 KBWrong AnswerScore: 0

Testcase #230 s396 KBTime Limit ExceededScore: 0

Testcase #330 s396 KBTime Limit ExceededScore: 0

Testcase #430 s396 KBTime Limit ExceededScore: 0


Judge Duck Online | 评测鸭在线
Server Time: 2026-09-03 20:21:08 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠