// References:
// - saffah_cc_v41_agg1, https://duck.ac/submission/106331: copied its accepted 1009b 3D engine and retained inherited citations; no separate license notice was displayed.
// - saffah_codex_6s_agg2, https://duck.ac/submission/107426: used the GCC loop-unrolling, register-renaming and loop-alignment scheduling idea previously measured on our own 1013b code.
// Approach: Change only the GCC optimization pragma on the current 1009b engine; the data structures and operations are identical.
// Purpose: Experimental official Try It timing and hash verification of compiler schedule variants.
// ===== REFERENCES =====
// [1] duck.ac 用户 saffah_codex_6s_agg2,提交 #106226 <https://duck.ac/submission/106226>(0.358691 ms,当代 T)。
// 用途:**本发的三处改动全部是它的**(公开提交,逐行 diff 得到 —— 它相对我方 #106029 只多了这三处)。
// 本件正文 = 我方 #106029 正文 + 这三处的移植(故与它不构成同源重复件)。
// [2] 本账号 saffah_cc_v41_agg1,提交 #106029 <https://duck.ac/submission/106029>(0.364953 ms)
// 用途:**本文件的直接基底**(`work/e9x_v4.cpp`),含我方 SIMD 前缀扫描刀。
// [3] BRIEF §2.18.973(对手取证)/ §2.19.007(复刻切点:注释区之后的第一行代码起切)。
// ======================
// ===== 思路 =====
// ★ **[X14B-BSCAN] 本发在基底 #106246 上再加的唯一一处改动(单变量、逐位等价改写)**:
// **把每个分组的边界扫描并进第一趟**,消掉对 `QA` 的第二遍整程遍历。
// 原形态(`work/e9x_v5_sub.cpp`):
// while (p<n) { int q=p+1; xv=QA[p]&0x3FFF;
// while (q<n && (QA[q]&0x3FFF)==xv) q++; // ← 把 [p,q) 再走一遍
// for(e=p;e<q;e++){ m=QA[e]; … } // ← pass 1 也走这一遍
// for(e=p;e<q;e++){ b=QB[e]; … } p=q; }
// ⇒ 每个元素被 `QA` 载入两次、分支两次。本发把边界探测并进 pass 1:
// for(e=p;e<n;e++){ m=QA[e]; if(e>p && (u32)(m&0x3FFF)!=xv){ q=e; break; } …body…; q=e+1; }
// ⇒ **`q` 仍等于「第一个 x 与 `xv` 不同的小标,否则 n」**,与原 while 完全一致 ⇒ 逐位等价。
// `QA` 的第二遍遍历消失;pass 1 循环体、pass 2、以及"两趟必须分开"的语义(pass 2 就地改
// `YZ/ZY/H`,同组内元素不得互相看到)**全部未动**。
//
// 【定价依据】判题机同二进制 A/B(`work/x14b_bscan.py` 的运行期开关,full-size n=10000、
// min-of-5、重复基臂):**基臂 1,092,228 / 1,092,694 cyc,本形态 1,081,472 cyc ⇒ −10,756 cyc
// = −0.98%**(基臂复现 0.04%)。缺口 3.149 µs(严支 0.99*T = 0.356104)⇒ 按 0.98% 估 **−3.52 µs**。
// 消融上界(`work/x14b_ab2.py` 的 `no-BSCAN` 敲除臂)= **80,506 cyc = 7.4%**;敲除臂给的是"这块占
// 多少"、不是"这样改值多少",故以 A/B 的 −0.98% 为准。
// 【闸门】① `work/e9x_gate.py e9x_v5_sub.cpp x14b_bscan_prod.cpp` ⇒ **7/7 mode 逐位相同**(含
// mode2 `x=i` 全序、mode3 重平局、mode5 `x%64` 三个对抗形态);② 判题机 A/B 两臂 checksum 全等
// (`856d7e588c74edc2`)。
// 【可证伪的判据】判题机 **< 0.359253 ms** 为正;**≤ 0.356104 ms(0.99*T + 1µs)直接达标**。
// ⚠ 本题已知陷阱(`notes.md` §QPACK):探针是同进程**热态取 min**,正式判题是**单次冷跑**
// ⇒ 探针**正**读数不保证迁移(QPACK 探针 −0.48% ⇒ 正式 +0.23%);负读数可信。故以正式提交定价。
// 正式提交(非试验性)。**单变量**(一个整体 = 对手 #106226 相对我方的全部增量,三处同源):
// ① `#define XB 256 -> 288`(记录环容量;对手的调定值);
// ② 前缀桥接 5 条指令 -> 3 条:`_mm256_permute2x128_si256(x,x,0x08)` 的**低半区被清零**、高半区取 x.lo,
// 故 `add_epi16(x, shuffle_epi8(它, b7w))` 等价于原来的
// `castsi128(lo) / extracti128 / shuffle / add / inserti128`(低半区不变、高半区加 bcast(lo[14,15]))⇒ **逐位等价**;
// ③ **`scanbrec` 改为按 `nrec` 自适应**:恒扫 3 块(96 B),`nrec>96` 再扫 3 块,`nrec>192` 再扫 3 块
// (原来固定 `XB>>5 = 8` 块)。**正确性证明**:`padrec()` 把环尾填 **0x7F**,而 `cmpgt_epi8(ty,0x7F)`
// 与 `cmpgt_epi8(tz,0x7F)` 对 `fy,fz <= 78` **恒假** ⇒ 越过 `nrec` 的块**贡献恒为 0** ⇒ 跳过它们严格等价。
//
// 【证据】逐行 diff(§2.19.007 切点:注释区之后第一行代码起)⇒ 对手相对我方只有这三处;
// 三处合起来在判题机上:**我方 1,193,244 cyc -> 1,166,588 cyc(同 TU warm-min-of-200)=-2.23%**。
// 【闸门】① `work/e9x_gate.py`(两个独立可执行 × 7 mode)⇒ **7/7 逐位相同**(chk 全等);
// ② 对手件本身在判题机上 Accepted(其正文即本件的三处来源);③ 无输出接口(`count_3d` 写 `out`)。
// 【可证伪的判据】判题机用时 < 0.364953 ms 即为正;<= 0.356104 ms(= 0.99*T + 1µs)则直接达标。
// ⚠ 注意:我方刷新最好件后口径转**严支**(现在 T 的 id 106226 > 我方 106029 ⇒ 当前是宽支 1.005*T = 0.361484)。
// ================
// ===== REFERENCES =====
// [1] duck.ac 用户 saffah_codex_6s_agg2,提交 #105317 <https://duck.ac/submission/105317>
// 用途:**本文件正文出自该提交**(= 本账号 #103889 + 2 处 hunk)。完备性已证:本账号
// #103889 正文 + `rebuild_cp` 内 2 处 hunk + 1 处 pragma 改动 == 该提交正文,逐字节相同
// ⇒ 其读数 0.408730 ms 即本基座的读数。
// [2] 本账号 saffah_cc_v41_agg1,提交 #103889 <https://duck.ac/submission/103889>
// 用途:基座的全部其余结构(u8 块号 ragged 扫描、XB=128、三趟规约合一)。
// [3] duck.ac 用户 saffah_codex_6s_agg2,提交 #103792 / #102725
// <https://duck.ac/submission/103792> <https://duck.ac/submission/102725>
// 用途:u8 化之前的扫描形态与「通道累加 + 单次 vpsadbw」规约。
// [4] 本账号 saffah_cc_v41_agg1,提交 #102781 / #99761 / #101142
// <https://duck.ac/submission/102781> <https://duck.ac/submission/99761>
// <https://duck.ac/submission/101142>
// 用途:`scanv()` 的「固定行程 + 逐向量通道掩码」与 SIMD 通道累加。
// [5] duck.ac 用户 saffah_cc_v41_260924,提交 #101112 / #99644
// <https://duck.ac/submission/101112> <https://duck.ac/submission/99644>
// 用途:引擎骨架(x 分组扫描 + (y,z) 按 BB 分块二维前缀表 CP + ragged 边表 YZ/ZY +
// 小环 rec)与 u16 rank 打包思想源自这两代公开实现(继承自 [2])。
// 以上均为 duck.ac 公开提交,未见许可证声明;按其公开可读性引用并注明原作者与地址。
// ======================
// ===== 思路 =====
// 【单变量】分块边长 **BB 256 → 128**(`engine_t<40,48>` → `engine_t<79,80>`),
// 其余一字未改。
// 【动机】notes 里 BB=128 的旧读数(+2.31%)取自**上一代基座**(XB=64、两条 ragged 扫描
// 都是 u16)。本基座有两处前提已变,属 BRIEF §2.18.863②「换基座必须重扫整轴」:
// ① XB 64→128 ⇒ `rebuild_cp` 的每查询摊销直接减半;② ZY/环已 u8 化。
// 解析账(判题机 probe,正反两序各一次、同 TU 5 臂交替、21 轮取最小):
// A0 = 本基座 BB=256 : 1,325,798 / 1,329,782 cyc
// A1 = BB=192 (S=64) : +2.98% / +3.50% ✗ 更差
// A2 = BB=160 (S=64) : +0.85% / +0.83% ✗ 更差
// A3 = BB=128 (S=80) : **−1.29% / −1.05%** ✓
// A4 = 与 A0 逐字节相同的伪臂(噪声地板): +0.22% / +0.32%
// ⇒ A3 在两序里都比伪臂低 1.05~1.51 个百分点,符号一致。
// 换算:probe cyc × 0.3083 µs/kcyc = 真机 ms(用 A0 ↔ #105317 的 0.408730 ms 标定,
// 误差 <0.01%);A3 ⇒ ≈403.5~404.4 µs。
// 【正确性】本机 `-DBRUTE` 与 O(n²) 暴力逐位对拍:n=2000 × mode{0..4} 与 n=10000 × mode0,
// 五臂 bad=0 且 FNV 校验和逐位相同(`work/b9a_probe_bb.cpp`)。
// 【代价】BB=128 让 `rebuild_cp` 的 CP 表从 40×48 涨到 79×80(重建更贵,每 XB=128 次插入
// 一次),但两条 ragged 扫描的行程从 16/8 条向量降到 8/4 条 ⇒ 净赚。
// ================
#include <string.h>
#include <immintrin.h>
#pragma GCC push_options
#pragma GCC optimize("O3","unroll-loops","rename-registers","align-loops=32")
#pragma GCC target("avx2,popcnt,tune=skylake")
typedef unsigned u32;
typedef unsigned short u16;
typedef unsigned long long u64;
typedef unsigned char u8;
#define AVX2 __attribute__((target("avx2")))
#define BB 128
#define XB 288 /* [e9x 2nd seat] XB 256->288, ported from rival #106226 (byte-for-byte his value) */
#define BLKIDX(r) ((int)((r) / BB))
#define BLOFF(v) ((int)((v) % BB))
#define BLK0(f) ((f) * BB)
#ifndef MAXN
#define MAXN 100005
#endif
#define MAXG 640
#define SENTB 0x7F7F
static u16 H[MAXG * 320];
static u16 CP[MAXG * 320];
static u16 YZ[MAXN + 32];
static u8 ZY[MAXN + 32];
static u8 recY[XB + 32], recZ[XB + 32];
static signed char laneB[BB];
static u16 cnt[MAXN + 2], stv[MAXN + 2], curs[MAXN + 2];
static u32 ordx[MAXN + 2];
static u64 QA[MAXN + 2];
static u32 QB[MAXN + 2];
static u64 meta[MAXN + 2];
/* [e9x] 16-lane u16 exclusive scan: stv[] and curs[] both take the exclusive prefix.
Sums reach n=10000 < 65536 so u16 is exact; bit-identical to the scalar serial form. */
AVX2 static inline void pfx16(const u16 *c, u16 *a1, u16 *a2, int n) {
const __m256i b7w = _mm256_setr_epi8(14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,
14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15);
__m256i carry = _mm256_setzero_si256();
int v = 0;
for (; v + 16 <= n + 1; v += 16) {
__m256i o = _mm256_loadu_si256((const __m256i *)(c + v));
__m256i x = o;
x = _mm256_add_epi16(x, _mm256_slli_si256(x, 2));
x = _mm256_add_epi16(x, _mm256_slli_si256(x, 4));
x = _mm256_add_epi16(x, _mm256_slli_si256(x, 8));
x = _mm256_add_epi16(x, _mm256_shuffle_epi8(
_mm256_permute2x128_si256(x, x, 0x08), b7w));
__m256i acc = _mm256_add_epi16(x, carry);
__m256i ex = _mm256_sub_epi16(acc, o);
_mm256_storeu_si256((__m256i *)(a1 + v), ex);
_mm256_storeu_si256((__m256i *)(a2 + v), ex);
carry = _mm256_shuffle_epi8(_mm256_permute2x128_si256(acc, acc, 0x11), b7w);
}
u32 a = (v == 0) ? 0u : (u32)_mm256_extract_epi16(carry, 0);
for (; v <= n; v++) { u32 cc = c[v]; a1[v] = (u16)a; a2[v] = (u16)a; a += cc; }
}
static u16 maskTab[17][16] __attribute__((aligned(32)));
static int gS;
static u16 ZERO_CP_ROW[320] __attribute__((aligned(32)));
AVX2 static inline __m256i ldu256(const void *p) { return _mm256_loadu_si256((const __m256i *)p); }
AVX2 static inline void stu256(void *p, __m256i v) { _mm256_storeu_si256((__m256i *)p, v); }
AVX2 static inline u32 hsum8(__m256i s) {
__m128i lo = _mm256_castsi256_si128(s), hi = _mm256_extracti128_si256(s, 1);
__m128i t = _mm_add_epi32(lo, hi);
t = _mm_add_epi32(t, _mm_shuffle_epi32(t, _MM_SHUFFLE(1, 0, 3, 2)));
t = _mm_add_epi32(t, _mm_shuffle_epi32(t, _MM_SHUFFLE(2, 3, 0, 1)));
return (u32)_mm_cvtsi128_si32(t);
}
AVX2 static inline __m256i scanv(const u16 *v, int off, int thr) {
/* FIXED-TRIP-COUNT: always scan all BB/16 = 16 vectors, masking the lanes
at/after `off` with a running "remaining" vector. Bit-identical to the
data-dependent form above, but the loop-exit branch is always predictable. */
const __m256i t = _mm256_set1_epi16((short)thr);
const __m256i lane = _mm256_setr_epi16(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
const __m256i step = _mm256_set1_epi16(16);
__m256i rem = _mm256_set1_epi16((short)off);
__m256i acc = _mm256_setzero_si256();
const u16 *p = v;
for (int r = 0; r < (BB >> 4); r++, p += 16) {
__m256i c = _mm256_and_si256(_mm256_cmpgt_epi16(t, ldu256(p)),
_mm256_cmpgt_epi16(rem, lane));
acc = _mm256_sub_epi16(acc, c);
rem = _mm256_sub_epi16(rem, step);
}
return acc;
}
/* u8 block-index scan: `value < thr` over 32-byte vectors. thr is a block index
(<= 78) and the sentinel is 0x7F, so signed vpcmpgtb is exact for the value
test. The positional cut is unsigned -- (off ^ 0x80) >signed (lane ^ 0x80) --
so off may range over [0,256); laneB[] holds (32r + lane) ^ 0x80 as a signed
byte and is built once per call. The accumulator counts UP. */
AVX2 static inline __m256i scanb(const u8 *v, int off, int thr) {
const __m256i t = _mm256_set1_epi8((char)thr);
const __m256i k = _mm256_set1_epi8((char)(off ^ 0x80));
__m256i acc = _mm256_setzero_si256();
const u8 *p = v;
for (int r = 0; r < (BB >> 5); r++, p += 32) {
__m256i c = _mm256_and_si256(_mm256_cmpgt_epi8(t, ldu256(p)),
_mm256_cmpgt_epi8(k, ldu256(laneB + 32 * r)));
acc = _mm256_sub_epi8(acc, c);
}
return acc;
}
/* ring twin: no positional mask needed -- padrec() keeps the tail at 0x7F and
0x7F fails both tests (fy <= 78 < 127). */
AVX2 static inline __m256i scanbrec(int fy, int fz, int nrec) {
const __m256i ty = _mm256_set1_epi8((char)fy);
const __m256i tz = _mm256_set1_epi8((char)fz);
__m256i acc = _mm256_setzero_si256();
const u8 *py = recY, *pz = recZ;
for (int r = 0; r < 3; r++, py += 32, pz += 32)
acc = _mm256_sub_epi8(acc, _mm256_and_si256(_mm256_cmpgt_epi8(ty, ldu256(py)),
_mm256_cmpgt_epi8(tz, ldu256(pz))));
if (nrec > 96)
for (int r = 3; r < 6; r++, py += 32, pz += 32)
acc = _mm256_sub_epi8(acc, _mm256_and_si256(_mm256_cmpgt_epi8(ty, ldu256(py)),
_mm256_cmpgt_epi8(tz, ldu256(pz))));
if (nrec > 192)
for (int r = 6; r < 9; r++, py += 32, pz += 32)
acc = _mm256_sub_epi8(acc, _mm256_and_si256(_mm256_cmpgt_epi8(ty, ldu256(py)),
_mm256_cmpgt_epi8(tz, ldu256(pz))));
return acc;
}
AVX2 static inline void padrec(void) {
for (int k = 0; k < XB + 16; k++) { recY[k] = 0x7F; recZ[k] = 0x7F; }
}
template <int TS> AVX2 static void rebuild_cp(int G) {
const int S = (TS > 0) ? TS : gS;
const __m256i bcastLast = _mm256_setr_epi8(14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,
14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15);
int fy = 0;
for (; fy + 1 < G; fy += 2) {
const u16 *h0 = H + (size_t)fy * S, *h1 = h0 + S;
u16 *c0 = CP + (size_t)fy * S, *c1 = c0 + S;
const u16 *pv = fy ? CP + (size_t)(fy - 1) * S : ZERO_CP_ROW;
__m256i k0 = _mm256_setzero_si256(), k1 = _mm256_setzero_si256();
for (int j = 0; j < S; j += 16) {
__m256i v0 = ldu256(h0 + j), v1 = ldu256(h1 + j);
v0 = _mm256_add_epi16(v0, _mm256_slli_si256(v0, 2));
v1 = _mm256_add_epi16(v1, _mm256_slli_si256(v1, 2));
v0 = _mm256_add_epi16(v0, _mm256_slli_si256(v0, 4));
v1 = _mm256_add_epi16(v1, _mm256_slli_si256(v1, 4));
v0 = _mm256_add_epi16(v0, _mm256_slli_si256(v0, 8));
v1 = _mm256_add_epi16(v1, _mm256_slli_si256(v1, 8));
v0 = _mm256_add_epi16(v0, _mm256_shuffle_epi8(_mm256_permute2x128_si256(v0, v0, 0x08), bcastLast));
v1 = _mm256_add_epi16(v1, _mm256_shuffle_epi8(_mm256_permute2x128_si256(v1, v1, 0x08), bcastLast));
__m256i r0 = _mm256_add_epi16(v0, k0), r1 = _mm256_add_epi16(v1, k1);
k0 = _mm256_shuffle_epi8(_mm256_permute2x128_si256(r0, r0, 0x11), bcastLast);
k1 = _mm256_shuffle_epi8(_mm256_permute2x128_si256(r1, r1, 0x11), bcastLast);
__m256i d0 = _mm256_add_epi16(r0, ldu256(pv + j));
stu256(c0 + j, d0);
stu256(c1 + j, _mm256_add_epi16(r1, d0));
}
}
for (; fy < G; fy++) {
const u16 *h = H + (size_t)fy * S;
u16 *c = CP + (size_t)fy * S;
const u16 *pv = fy ? CP + (size_t)(fy - 1) * S : ZERO_CP_ROW;
__m256i k = _mm256_setzero_si256();
for (int j = 0; j < S; j += 16) {
__m256i v = ldu256(h + j);
v = _mm256_add_epi16(v, _mm256_slli_si256(v, 2));
v = _mm256_add_epi16(v, _mm256_slli_si256(v, 4));
v = _mm256_add_epi16(v, _mm256_slli_si256(v, 8));
v = _mm256_add_epi16(v, _mm256_shuffle_epi8(_mm256_permute2x128_si256(v, v, 0x08), bcastLast));
__m256i r = _mm256_add_epi16(v, k);
k = _mm256_shuffle_epi8(_mm256_permute2x128_si256(r, r, 0x11), bcastLast);
stu256(c + j, _mm256_add_epi16(r, ldu256(pv + j)));
}
}
}
template <int CG, int CS> static void engine_t(int n, const unsigned *x, const unsigned *y, const unsigned *z, unsigned *out) {
constexpr int TSC = CS;
if (n <= 1) { if (n == 1) out[0] = 0; return; }
const int G = (CG > 0) ? CG : ((n + BB - 1) / BB);
const int S = (CS > 0) ? CS : ((G + 15) & ~15);
gS = S;
if (S > 320 || G > 640 || n + 32 > MAXN) { for (int i = 0; i < n; i++) out[i] = 0; return; }
for (int i = 0; i < 17; i++)
for (int j = 0; j < 16; j++) maskTab[i][j] = (u16)(j < i ? 0xFFFFu : 0u);
for (int i = 0; i < BB; i++) laneB[i] = (signed char)(i ^ 0x80);
/* ---- y and z ranks in one fused pass ---- */
memset(cnt, 0, (size_t)(n + 1) * 2);
for (int i = 0; i < n; i++) cnt[y[i]]++;
pfx16(cnt, stv, curs, n);
for (int i = 0; i < n; i++) { u32 v = y[i]; meta[i] = ((u64)stv[v] << 48) | (u64)curs[v]++; }
memset(cnt, 0, (size_t)(n + 1) * 2);
for (int i = 0; i < n; i++) cnt[z[i]]++;
pfx16(cnt, stv, curs, n);
for (int i = 0; i < n; i++) { u32 v = z[i]; meta[i] |= ((u64)stv[v] << 32) | ((u64)curs[v]++ << 16); }
/* ---- x order ---- */
memset(cnt, 0, (size_t)(n + 1) * 2);
for (int i = 0; i < n; i++) cnt[x[i]]++;
pfx16(cnt, stv, curs, n);
for (int i = 0; i < n; i++) { u32 v = x[i]; ordx[curs[v]++] = i; }
for (int e = 0; e < n; e++) {
const int i = ordx[e];
const u64 m = meta[i];
unsigned xv = x[i];
if (xv > 0x3FFF) xv = 0x3FFF;
QA[e] = ((m >> 48) << 42) | ((((m >> 32) & 0xFFFF)) << 28) | ((u64)i << 14) | (u64)xv;
QB[e] = (u32)((m & 0xFFFF) | (((m >> 16) & 0xFFFF) << 14));
}
/* ---- structures (H/YZ/ZY are updated at INSERT time; CP is a snapshot) ---- */
memset(H, 0, (size_t)G * S * 2);
memset(CP, 0, (size_t)G * S * 2);
memset(YZ, SENTB, (size_t)n * 2 + 32);
memset(ZY, 0x7F, (size_t)n + 32);
padrec();
int nrec = 0;
int p = 0;
while (p < n) {
int q = p + 1;
const u32 xv = (u32)(QA[p] & 0x3FFF);
for (int e = p; e < n; e++) {
const u64 m = QA[e];
if (e > p && (u32)(m & 0x3FFF) != xv) { q = e; break; }
const u32 ky = (u32)(m >> 42), kz = (u32)((m >> 28) & 0x3FFF);
const int FY = (int)BLKIDX(ky), FZ = (int)BLKIDX(kz);
u32 c = (FY > 0 && FZ > 0) ? CP[(size_t)(FY - 1) * S + (FZ - 1)] : 0;
__m256i edge1 = scanv(YZ + ((size_t)BLK0(FY)), (int)BLOFF(ky), (int)kz);
__m256i edge2 = scanb(ZY + (size_t)BLK0(FZ), (int)BLOFF(kz), (int)FY);
__m256i recent = scanbrec((int)FY, (int)FZ, nrec);
__m256i all = _mm256_add_epi8(_mm256_add_epi8(edge1, edge2), recent);
__m256i sums = _mm256_sad_epu8(all, _mm256_setzero_si256());
__m128i halves = _mm_add_epi64(_mm256_castsi256_si128(sums), _mm256_extracti128_si256(sums, 1));
c += (u32)_mm_cvtsi128_si64(halves) + (u32)_mm_extract_epi64(halves, 1);
out[(m >> 14) & 0x3FFF] = c;
q = e + 1;
}
for (int e = p; e < q; e++) {
const u32 b = QB[e];
const u32 ry = b & 0x3FFF, rz = b >> 14;
H[(size_t)BLKIDX(ry) * S + BLKIDX(rz)]++;
YZ[ry] = (u16)rz;
ZY[rz] = (u8)BLKIDX(ry);
recY[nrec] = (u8)BLKIDX(ry);
recZ[nrec] = (u8)BLKIDX(rz);
if (++nrec == XB) { rebuild_cp<TSC>(G); nrec = 0; padrec(); }
}
p = q;
}
}
#pragma GCC pop_options
void count_3d(int n, const unsigned *x, const unsigned *y, const unsigned *z, unsigned *out) {
if (n == 10000) engine_t<79, 80>(n, x, y, z, out);
else engine_t<-1, -1>(n, x, y, z, out);
}
| Compilation | N/A | N/A | Compile OK | Score: N/A | 显示更多 |
| Testcase #1 | 329.01 us | 436 KB | Accepted | Score: 100 | 显示更多 |