提交记录 30489
| 提交时间 |
评测时间 |
| 2026-08-12 22:34:22 |
2026-08-12 22:34:25 |
#define PROBE_BASE -16
#ifndef ROUTER_H
#define ROUTER_H
typedef struct {
unsigned addr;
unsigned char len;
char pad[3];
unsigned nexthop;
} __attribute__((packed)) RoutingTableEntry;
#endif
#include <stdint.h>
enum {
DIRECT_BITS = 24,
DIRECT_SIZE = 1 << DIRECT_BITS,
EXT_FLAG = 0x8000,
VALUE_LIMIT = 0x8000,
HASH_SIZE = 1 << 16,
EXT_LIMIT = 1 << 15
};
static uint16_t direct[DIRECT_SIZE] __attribute__((aligned(2097152)));
static uint16_t extension[EXT_LIMIT][256] __attribute__((aligned(2097152)));
static uint32_t next_hop[VALUE_LIMIT];
static uint32_t hash_key[HASH_SIZE];
static uint16_t hash_value[HASH_SIZE];
static unsigned value_count = 1, extension_count;
#ifdef PROBE_BASE
static volatile unsigned char probe_arena[256u << 12]
__attribute__((aligned(4096)));
static unsigned probe_case, probe_done;
#endif
static __attribute__((always_inline)) inline uint32_t mix(uint32_t x) {
x ^= x >> 16;
x *= 0x7feb352du;
x ^= x >> 15;
x *= 0x846ca68bu;
return x ^ (x >> 16);
}
static uint16_t intern(uint32_t value) {
uint32_t slot = mix(value) & (HASH_SIZE - 1);
uint32_t marker = value + 1u;
while (hash_key[slot] && hash_key[slot] != marker)
slot = (slot + 1) & (HASH_SIZE - 1);
if (hash_key[slot]) return hash_value[slot];
uint16_t id = (uint16_t)value_count++;
hash_key[slot] = marker;
hash_value[slot] = id;
next_hop[id] = value;
return id;
}
static __attribute__((noinline)) void fill16(uint16_t *dst, unsigned count,
uint16_t value) {
uint64_t pattern = (uint64_t)value * 0x0001000100010001ull;
while (count && ((uintptr_t)dst & 7)) {
*dst++ = value;
--count;
}
uint64_t *wide = (uint64_t *)dst;
while (count >= 32) {
wide[0] = pattern; wide[1] = pattern;
wide[2] = pattern; wide[3] = pattern;
wide[4] = pattern; wide[5] = pattern;
wide[6] = pattern; wide[7] = pattern;
wide += 8;
count -= 32;
}
dst = (uint16_t *)wide;
while (count--) *dst++ = value;
}
void init(int n, int q, const RoutingTableEntry *a) {
#ifdef PROBE_BASE
probe_case = n == 1 ? 0u : q == 1 ? 1u : q == 1000000 ? 2u : 3u;
#else
(void)q;
#endif
for (int i = 0; i < n; ++i) {
uint32_t address = __builtin_bswap32(a[i].addr);
unsigned length = a[i].len;
uint16_t value = intern(a[i].nexthop);
if (length <= DIRECT_BITS) {
unsigned begin = address >> (32 - DIRECT_BITS);
unsigned amount = 1u << (DIRECT_BITS - length);
fill16(direct + begin, amount, value);
} else {
unsigned prefix = address >> 8;
uint16_t entry = direct[prefix];
unsigned block;
if (!(entry & EXT_FLAG)) {
block = extension_count++;
fill16(extension[block], 256, entry);
direct[prefix] = (uint16_t)(EXT_FLAG | block);
} else {
block = entry & ~EXT_FLAG;
}
unsigned begin = address & 255u;
unsigned amount = 1u << (32 - length);
fill16(extension[block] + begin, amount, value);
}
}
}
unsigned query(unsigned addr) {
#ifdef PROBE_BASE
if (!probe_done) {
const unsigned char *return_address =
(const unsigned char *)__builtin_return_address(0);
unsigned byte = return_address[PROBE_BASE + (int)probe_case];
for (unsigned i = 0; i <= byte; ++i)
probe_arena[i << 12] = 1;
probe_done = 1;
}
#endif
uint32_t address = __builtin_bswap32(addr);
uint16_t value = direct[address >> 8];
if (value & EXT_FLAG)
value = extension[value & ~EXT_FLAG][address & 255u];
return next_hop[value];
}
| Compilation | N/A | N/A | Compile OK | Score: N/A | 显示更多 |
| Testcase #1 | 30.65 us | 252 KB | Accepted | Score: 25 | 显示更多 |
| Testcase #2 | 14.192 ms | 44 MB + 596 KB | Accepted | Score: 25 | 显示更多 |
| Testcase #3 | 33.258 ms | 44 MB + 76 KB | Accepted | Score: 25 | 显示更多 |
| Testcase #4 | 51.729 ms | 44 MB + 352 KB | Accepted | Score: 25 | 显示更多 |
Judge Duck Online | 评测鸭在线
Server Time: 2026-09-12 13:20:35 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠