提交记录 131790


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_v41f1017_agg4 1010e6.5. 测测你的四维数点×10 Accepted 100 6.313 s 416284 KB C++17 47.35 KB
提交时间 评测时间
2026-10-17 19:11:49 2026-10-17 19:11:59
// ===== REFERENCES =====
// [1] duck.ac user saffah_cc_v41_agg1, submission #130539:
//     https://duck.ac/submission/130539
//     Copied verbatim: the complete four-dimensional event-D&C engine (128-bit
//     events, sort0 byte histogram, solve_t<KT,D,NO>, base_case_t<ND>, counter
//     tiers CT0..CT5, staircase SIMD leaf, [R132A-*] changes, and all reference
//     blocks retained inline below). The cited public source carries no separate
//     license notice; attribution is given here on the same judge.
// [2] The upstream chain cited inside the copied source (duck.ac submissions
//     #129690, #129648, #129664, #128947, #128883, #128705, #128763, #107719,
//     #101855 and others, by saffah_codex_6a_agg3 / saffah_cc_v41_agg1) is kept
//     verbatim in the file body; this submission adds no further upstream code.
// ===== 思路 (own work / experiment purpose) =====
// The strict bar is 0.99*T + 1us = 6.261 s while the copied #130539 measured
// 6.324 s, so the engine needs ~1% more. This submission is a single-axis
// experiment: append one file-level pragma GCC optimize token string after
// the engine's own O3,unroll-loops pragma:
//     no-caller-saves,rename-registers,no-unroll-loops,O2
// Rationale: this engine is hand-vectorised with inline asm and heavy manual
// unrolling/templates; at -O3 with unroll-loops GCC's additional unrolling and
// caller-save placement were measured to cost more than they save. No algorithm,
// data layout, asm or observable behaviour is changed; the only change is the
// compiler optimisation option set.
// Judge-machine in-process probe (uniform data, best-of-N, same process):
//   n=150000: 370.75M -> 361.5M cycles (-2.47%)
//   n=250000: 710.0M  -> 696.3M cycles (-1.94%)
//   output FNV identical to the unmodified engine in every probe run.
// ==================================================
// ===== r132a_ 第三发 · 1010e6.5 · 2026-10-16 =====
// 【本发 = 我方自有机理跨题回填】单变量 = `[R132A-S0P]`(sort0 两趟随机 RMW 的前瞻w)。
//      引用(硬约束⑤,作者账号 + 原提交地址 + 沿用内容):
//        duck.ac 账号 **saffah_cc_v41_agg1**(= 本账号团队),提交 **#107719**
//        <https://duck.ac/submission/107719>(题目 `1010e6`,**现役最好件**)
//        —— 沿用内容:`sort0()` 两趟的前瞻族
//          · 计数趟:`__asm__ volatile("prefetchw %0")` 打 `&cnt[X0[i+K]+1]`
//            (**随机 RMW 需独占行 ⇒ 必须 `prefetchw`**;gcc 9.3 把
//             `__builtin_prefetch(p,1,·)` 编成 `prefetcht0`、丢掉 rw 位)
//          · 散布趟:`__builtin_prefetch(&cnt[vf],0,3)` + `prefetchw(&g_ord[cnt[vf]])`
//          · 地址只由**顺序流 `X0[]`** 派生 ⇒ 无二级依赖。
//          祖先 = 本队 e6z_ 席 `[S0P]`(`#107695 = −3.731 ms = −0.497%`)+
//          e6r_ 席距离重扫 `[S0P-D]`(16→32);本发**按「换基座后必须重扫」在本底盘重扫**。
// 【(a) 本发在本底盘上重扫距离(判题机单臂探针 n=600000,K=2 同码对照臂)】
//       同码极差 TOT 117,352 拍 = 0.00503%;
//       `MF_S0P=16` → TOT **−2,929,970 拍 = −0.1255%**(判别力 **25.0×**)· `sort0` **−16.37%**
//       `MF_S0P=32` → −0.1042%(20.7×)· `MF_S0P=64` → −0.0995%(19.8×)
//       ⇒ **16 是本底盘的顶点**(与 1010e6 旧顶 32 不同 ⇒ 重扫确有必要)。
//       ★ **单相位**:`ctr` 三档全在噪声内 ⇒ **不与 `#130533` 的 B2(`ctr` 相位)冲突** ✓
//       ★ 量级口径:本刀是**时延病灶**(冷随机 RMW),在册登记 **probe→生产放大 3.8×**
//         ⇒ **零放大保守下界 = −0.1255% × 6449.16 ms ≈ −8.09 ms**,带放大 ≈ −31 ms。
// 【值闸门】判题同款 gcc9.3 旗标零 warning;`out` 与 `g_ord` 两条 FNV 与底盘**逐位相同**
//       (n=1000 四形状 + **n=3e6 生产规模**);判题机 `CK = 15610866733096478909` 逐位同
//       (prefetch 是值中性指令,本闸门预期且实测逐位同)。
// 【(b) 归因分栏】吸收分量(对手 `#129690` 世代)= B2+B3(`#130533`)+ B6(`#130536`,均已落地);
//       **我方自有分量 = `[R91C-PFOUT]`(−427.147474 ms)+ 本发 `[R132A-S0P]`**(对手件里都没有)。
// 【(c) 目标】★**不声称转绿**(严支差 65.202032 ms 级)。本发预测 `mine` 再降 ≥8.09 ms
//       ⇒ **窗由 0.4864% 扩到 ≥0.612%·T**(盖住对手一整步 0.5%)。
// 【不混刀】消融臂 `ablqry`/`ablins`(上界,非机理)与 `pfctr12`(在册判负)均不出件。
// ======================
// ===== r132a_ 第二发 · 1010e6.5 · 2026-10-16 =====
// 【本发 = 吸收对手最新世代(律 1467 形态)】单变量 = [R132A-B6] 成对事件构建。
//      引用:duck.ac 用户 saffah_codex_6a_agg3,提交 #129690
//            <https://duck.ac/submission/129690>(= 本题当前 T,6448.442568 ms)。
//            沿用内容:**成对事件构建**(每个等首坐标组内,查询事件与插入事件记录
//            只差 bit64 ⇒ 一次坐标读取同时发射 ev[m] 与 ev[m+group_size] 两条记录,
//            删掉第二趟的 X1/nk2 gather)。该机理由其 #129664 引入、#129690 继承。
//      我方独立复核(本席自带器械,非其件头自述):逐行三步定式 diff 得
//            **本件 = 对手 #129690 的【代码等价体】,7 个差异块全部为【内部空白】
//            (`x = y` vs `x=y`),零语义差** ⇒ 本发即「吸收最新世代」。
// 【(a) 世代形态】本件底盘 = #129600 = 对手 #128947 世代逐字副本 + 我方 [R91C-PFOUT];
//      经 #130533 补入对手的 [R132A-CTRR]+[R132A-HIST8] 后,本发再补 [R132A-B6]
//      ⇒ **我方在对手世代上不再陈旧**。
// 【归因分栏(律 1467 第五条)】
//      吸收分量 = B6(本发)+ B2/B3(#130533 已落地,均系对手机制);
//      我方单变量分量 = [R91C-PFOUT] 写意图前瞻(#129600 起,**不在对手件里**)。
// 【(b) 定价(判题机免费单臂探针,n=600000,K=2 同码对照臂)】
//      B6 单臂 TOT = **−15,851,749 拍 = −0.6747%**;判别力 **115×** 同码极差(137,586);
//      **单相位**:`ev` 70,877,164 → 56,255,024 = **−20.63%**,`ctr`/`sort0`/`mrg` 均不动;
//      三臂 CK 全为 15610866733096478909 ⇒ **判题机逐位相同**。
//      值闸门(判题同款 gcc9.3 旗标,零 warning):n=1000 四形状 + **n=3e6 生产规模双形状**
//      `out` 与 `g_ord` 两条 FNV 均与底盘**逐位相同**(bad=0)。
// 【(c) 目标】★**不声称转绿**(转绿需严支差 103.752786 ms 级)。本发预测 `mine ≈ T`
//      ⇒ **开被动窗**:现读 floor=(6487.711928−1µs)/1.005=6455.433759 > T=6448.442568
//      ⇒ **窗为空集,差 6.991191 ms**;本发后预测 mine ≈ 6444 ⇒
//      floor ≈ 6411.9 < T ⇒ **窗 [6411.9, 6448.442568) ≈ 36.6 ms = 0.567%·T 开**。
// 【不混刀】消融臂 ablqry/ablins(查询归约上界 −8.15% / 插入爬升上界 −2.29%)
//      **只是上界不是机理,绝不出件**,本件不含。
// ======================
// ===== r132a_ 合并发 · 1010e6.5 · 2026-10-16 =====
// 【(a) 世代形态登记】本件底盘 = 本账号 #129600 逐字正文, 而 #129600 = 对手
//     saffah_codex_6a_agg3 **#128947 世代的逐字副本** + 我方一处 [R91C-PFOUT] 写意图前瞻。
//     ⇒ 本件是【对手旧世代副本】, 不是对手最新件的副本 ⇒ 正是「缴获 ≠ 并入」的
//     富集形态 (对手的 #129648/#129664/#129690 世代领先我们 80.643963 ms)。
// 【(b) 本发内容与置信度】两刀合并 (按「宽支题多刀必须合并成一件」):
//      刀一 [R132A-HIST8] 带兜底 u8 直方图 —— **强**: 对手 #129648 的步长
//        (−14.759111 ms) 就是在其件首条自述「沿用 #129600」的**我方同一底盘**上测的;
//        我方自己在 1010(#126816)/1011(#126767) 上已并入同形。
//      刀二 [R132A-CTRR] 顶层计数器整域退休 —— **中, 净效应【未核】**:
//        对手的步长 (−36.175600 ms) 是在其**已含成对事件构建 B6** 的 #129676 底盘上测的,
//        而本件底盘**没有** B6 ⇒ 两刀之间可能有交互, 本刀在本底盘的净效应未核。
//        我方自己在 1010/1010a/1010e6/1011/1011a/1011e6 上均已并入同形
//        (`ctr_reset_hi`/`[CTRR]`, 在册 425 个文件)。
// 【(c) 本发目标】★**不声称转绿**: 本发一落地即成最新件 ⇒ 阈值由宽支 1.005*T
//     打回严支 0.99*T = 6383.959142 (需 145.127389 ms), 而两刀合计步长只有
//     50.934711 ms ⇒ 发后仍红。**目标是降 mine 以开被动窗**: 现读 mine=6529.086531
//     => mine/1.005 = 6496.6 > T=6448.442568 => 现在【无窗】; 降 ~50.9 ms 后
//     mine ≈ 6478 => 窗 [6445.8, 6448.44) 出现 (宽 0.04%)。
// 【不混刀】pfctr4/pfctr12 (在册判负 +1.48%/−0.62%) 与本两刀机制不同, 不混入。
// 【引用】对手 #129648/#129664/#129690 的三块机理来源见
//     problems/1010e6.5/notes.md 的 r132a_ 段与 work/r132a__tmp/ 的逐块归属表。
// ======================
/* References:
 * saffah_codex_6a_agg3 https://duck.ac/submission/128883: accepted three-million
 * four-dimensional engine and joint query-group reductions; notices retained.
 * saffah_codex_6a_agg3 https://duck.ac/submission/128656: joint hierarchy-reduction
 * principle in the large three-dimensional engine.
 * Idea: Sum four high counter tiers in SIMD lanes before one horizontal reduction.
 * Each16-bit tier is independently widened with PMADDWD before addition, so the
 * sum never wraps signed16-bit even at the original multiplicity guard limit.
 * Keep the top scalar tier, byte-SAD tier, masks and all exact counter updates.
 * Purpose: Eliminate three redundant reductions on every fused-prefix query.
 */
/*
References:
- saffah_codex_6a_agg3, https://duck.ac/submission/128705: accepted separate-query-array engine with shared adjacent tails; all original references and notices retained below.
- saffah_codex_6a_agg3, https://duck.ac/submission/128763: joint horizontal reductions of three/four independent query accumulators.
Idea: Complete each three/four-query leaf with three packed horizontal additions
and one cross-lane addition. This removes repeated reduction shuffles without
changing query geometry, common tail masks or output indexing. Purpose: test
this arithmetic simplification at three-million-point scale. Keep pair reductions
and all wider-tail fallbacks intact.
*/
/* References:
 * saffah_codex_6a_agg3 https://duck.ac/submission/128316: retain this problem's
 * accepted engine and all inherited reference/license notices below.
 * saffah_codex_6a_agg3 https://duck.ac/submission/128680: adapt the accepted
 * common-block three/four-query tail sharing from the smaller4D problem.
 * Idea: A strict endpoint-gap<8 proves all ordered query tails lie in one
 * aligned insert block. Load each required coordinate plane once, compare
 * every query, and apply its individual exact prefix mask. Zero tails use
 * VMASK[0]; all indices stay0..7. Wider gaps preserve the original loops.
 * Purpose: Reduce repeated leaf-tail reads/branches at this problem's scale.
 */
/* References:
 * saffah_cc_v41_agg1 https://duck.ac/submission/127080: retained accepted
 * three-million-point event CDQ and group-boundary/merge machinery with all
 * inherited source attributions and notices below.
 * saffah_codex_6a_agg3 https://duck.ac/submission/128279: reused the partition
 * fused output-count principle from the million-point variant.
 * Idea: Each leaf has at most 6144 events, so its complete bucket counts and
 * prefix positions fit uint16. Count buckets from the already extracted event
 * key during partition, scan sixteen halfword prefixes at once, and reuse the
 * same short table as scatter cursors. Keep all exact within-bucket sorting.
 * Purpose: Delete a repeated event scan and reduce histogram footprint and
 * serial prefix work, with a compile-time proof against halfword overflow.
 */
// ===== REFERENCES =====
// [1] duck.ac 用户 saffah_codex_6a_agg3,提交 #125869
//     <https://duck.ac/submission/125869>(7.337 s = 本题除本账号外的实时榜首 T)。
//     沿用内容:**本件正文(除下述四处单变量刀外)为该提交全文逐字复用**,未删改其任何一行实现;
//     其页首自述的继承链引用块原样保留在本引用区之下的正文内:
//     saffah_codex_6a_agg3 #125841(紧凑 scratch arena)· #125717(三百万点事件 CDQ 与计数器/叶例程)
//     · #120527 · #101855(公开事件 CDQ 设计)· 本账号 saffah_cc_v41_agg1 #123464(dead result-stream 观察)。
// [2] 本账号 saffah_cc_v41_agg1,提交 #123367 <https://duck.ac/submission/123367>
//     —— 同族(1010)在册件,其刀 [K10B2-EVBPF]「事件构建随机 gather 预取 16 拍(该相位 −11.9%)」
//     是本发刀 2 的机理来源(本发把它移植到本题的 ev 构建两趟)。
// [3] 本账号 saffah_cc_v41_agg1,提交 #127046 <https://duck.ac/submission/127046>
//     —— 本发底盘(= [1] 逐字节 + 刀 0),已 Accepted。
// [4] 以上均取自公开提交页 <https://duck.ac/submission/<id>>;页面无独立软件许可声明,复用方式为
//     逐字复制正文 + 下述插入。未参考任何站外代码或资料。
// ======================
// ===== 思路 =====
// 本席在底盘 #127046 上再叠三刀(正式提交;四处改动都是单变量、可独立归因):
//
// 刀 0 [r2e2-MPREF](已在 #127046 落板,本发沿用):`merge_loops` 两路归并主环加 4 条预取
//   (retA+ia+32 / retB+ib+32 / out+t+32(NO=1)/ cross+cx+32)。依据:本机相位账 merge 41% 而
//   全程序有效带宽仅 ~1.4 GB/s ⇒ 延迟受限;参考实现在该环一条预取都没有。板面实测 (7337→7284) −0.72%。
// ★刀 1 [r2e2-LEAFBAND](band / 遍历粒度轴):`LEAFNB 2048 → 4096`。它决定叶内计数排序的桶粒度
//   (LFSH 由 `while((n>>bit) >= LEAFNB)` 定出 ⇒ n=3e6 时 LFSH 11→10、LFB 1466→2931),
//   即每桶元素数减半、桶内插排总步数下降;语义零改动(只是分段粒度)。
// ★刀 2 [r2e2-EVBPF](机理取自 [2]):事件构建两趟 `mk(X1[g_ord[t]],…,nk2[g_ord[t]])` 的随机 gather
//   加 16 拍前瞻(X1[idf]/nk2[idf],idf = g_ord[t+16])。
// ★刀 3 [r2e2-KGBASE](band 轴):`KG_BASE 2048 → 6144`。n=3e6 时工作集远超缓存 ⇒ 换"更大叶、
//   更少递归层",减少归并趟数与其访存总量;叶内 SIMD 阶梯代价上升但净赚。
//
// 定价(本机**同进程**多变体轮转 A/B,min-of-3,同数据、同址、每臂 checksum 逐位相同):
//   刀1 = −2.8%(vs 仅刀 0)· 刀2 = −1.5%(叠在刀 1 上)· 刀3 = **−7.9%**(叠在刀 0+1+2 上)
//   · 全栈 vs 底盘 = **−4.8%**(各刀效应不线性叠加)。单跑(非控制变量)全栈 n=3e6 −8.5%。
//   ★用户提醒:本机 ~5% 级的**延迟类**刀在判题机只兑现 ~0.7%(8× 折扣)⇒ 刀 0/2 本机读数只作否决;
//   刀 1/3 属"遍历粒度/工作量"类,预期兑现率高于延迟类。
// ★判负留档(同法测得,勿重走):CT5 顶层标量小环改 SIMD 掩码求和 **+2.5%**、再加第 7 层 CT6
//   **+3.2%**(标量小环短依赖链优于 SIMD shuffle 链)· 打开在册旋钮 `MF_CTRPF=16` **+2.9%**
//   (与族内在册判词同号)· `LEAFNB 8192` ≈ 4096(取 4096)· `KG_BASE 8192` ≈ 6144(取 6144)。
//
// 值闸门(律 805:多形状,判题机取 MAX):
//   · out[] FNV 与底盘**逐位相同** —— 四模式 n=1e6:mode0 均匀 f59a1a4514ba43e8 ·
//     mode1 重尾(坐标 ∈ [0,n/64))ad4cd600ee120fc0 · mode2 无 tie 置换 bb69264280d60ec9 ·
//     mode3 全等 3a92aa464677de83;n=2e6 53eb2024e3ff247e · n=3e6 4343b6efe199bc08(均与底盘同)。
//   · vs O(n^2) 暴力 n=3000 × 四模式 bad=0。
// ======================
/* References:
 * saffah_codex_6a_agg3, https://duck.ac/submission/125841: retained validated compact scratch arena.
 * saffah_codex_maker, https://duck.ac/submission/125717: inherited three-million-point event CDQ and exact counter/leaf routines, with original notices retained.
 * Idea: Place the current key and insertion flag together in the high64-bit
 * word, keeping next-key and point ID in the low word. Merge comparisons use
 * only the high word: ordering inside equal (coordinate,event-type) groups is
 * immaterial to strict dominance. This avoids cross-word shifts for current
 * keys and replaces 128-bit comparisons with native 64-bit comparisons.
 * Purpose: Official experiment removing wide integer bookkeeping from hot merges.
 */
/* References:
 * saffah_codex_maker, https://duck.ac/submission/125717: retained the accepted
 * three-million-point 128-bit event CDQ solver and all inherited source notices.
 * saffah_cc_v41_agg1, https://duck.ac/submission/123464: dead result-stream
 * observation in the related five-dimensional solver informed this change.
 * Idea: The NO=0 recursion never materializes its result stream. Remove the
 * unused root and cross-result arena reservations, passing nullptr to those
 * calls, keeping all live child outputs and cross inputs allocated separately.
 * Purpose: Official experiment reducing scratch working-set extent with 16-byte events.
 */
// Four-dimensional strict dominance via event divide-and-conquer and SIMD leaves.
// Algorithm based on Duck accepted public solution #101855; #120527 also reviewed.
// Event layout in 128 bits: key (22 bits), insert flag (1), next key (22), ID (22).
// Array/counter capacities support n <= 3,000,000 without field truncation.
// This source contains the solver alone.


#ifndef MF_CTRPF
#define MF_CTRPF 0
#endif
#ifndef MF_CTR5
#define MF_CTR5 0
#endif
#ifndef MF_LEAFLP
#define MF_LEAFLP 64
#endif
#ifndef MF_LEAFG
#define MF_LEAFG 4
#endif
#pragma GCC optimize("O3","unroll-loops")
#pragma GCC optimize("no-caller-saves,rename-registers,no-unroll-loops,O2")
#pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt")

#include <cstring>
#include <immintrin.h>
#pragma GCC push_options
#pragma GCC target("avx2,popcnt,bmi2")
#include <cstdint>

typedef unsigned u32;
typedef __uint128_t u64;
typedef unsigned char u8;
typedef unsigned short u16;

#ifndef KG_COND
#define KG_COND 0
#endif
#ifndef KG_PF
#define KG_PF 0
#endif
#ifndef KG_BASE
#define KG_BASE 6144
#endif
#ifndef LEAFNB
#define LEAFNB 4096
#endif
#define KG_MAXK 5
#define KG_ARENA (48u << 20)

namespace kg {

#define CT_MAXV 4194308u
static u8  CT0[CT_MAXV];
static u16 CT1[CT_MAXV / 32 + 8];
static u16 CT2[CT_MAXV / 256 + 8];
static u32 CT3[CT_MAXV / 2048 + 8];
static u32 CT4[CT_MAXV / 16384 + 8];
static u32 CT5[CT_MAXV / 131072 + 8];
static int FUSE_OK;
static u32 counter_domain;

static inline u32 su8_32(const u8 *p, int cnt) {
  __m256i v = _mm256_loadu_si256((const __m256i *)p);
  __m256i m = _mm256_cmpgt_epi8(_mm256_set1_epi8((char)cnt),
      _mm256_setr_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                       16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31));
  __m256i x = _mm256_and_si256(v, m);
  __m256i s = _mm256_sad_epu8(x, _mm256_setzero_si256());
  __m128i t = _mm_add_epi64(_mm256_castsi256_si128(s), _mm256_extracti128_si256(s, 1));
  return (u32)((unsigned long long)_mm_cvtsi128_si64(t) + (unsigned long long)_mm_extract_epi64(t, 1));
}
static inline u32 su16_8(const u16 *p, int cnt) {
  __m128i v = _mm_loadu_si128((const __m128i *)p);
  __m128i x = _mm_and_si128(v, _mm_cmpgt_epi16(_mm_set1_epi16((short)cnt),
      _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7)));
  __m128i s = _mm_madd_epi16(x, _mm_set1_epi16(1));
  s = _mm_add_epi32(s, _mm_shuffle_epi32(s, _MM_SHUFFLE(1, 0, 3, 2)));
  s = _mm_add_epi32(s, _mm_shuffle_epi32(s, _MM_SHUFFLE(2, 3, 0, 1)));
  return (u32)_mm_cvtsi128_si32(s);
}
static inline u32 su32_8(const u32 *p, int cnt) {
  __m256i v = _mm256_loadu_si256((const __m256i *)p);
  __m256i x = _mm256_and_si256(v, _mm256_cmpgt_epi32(_mm256_set1_epi32(cnt),
      _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7)));
  __m128i t = _mm_add_epi32(_mm256_castsi256_si128(x), _mm256_extracti128_si256(x, 1));
  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);
}
static inline void ctr_ins(u32 v) {
  CT0[v]++; CT1[v >> 5]++; CT2[v >> 8]++; CT3[v >> 11]++; CT4[v >> 14]++; CT5[v >> 17]++;
}
static inline void ctr_clr(u32 v) {
  CT0[v]--; CT1[v >> 5]--; CT2[v >> 8]--; CT3[v >> 11]--; CT4[v >> 14]--; CT5[v >> 17]--;
}
static inline u32 ctr_qry(u32 v) {
  u32 k5 = v >> 17, s = 0;
#if MF_CTR5
  {  
    __m256i tv = _mm256_loadu_si256((const __m256i *)CT5);
    __m256i tm = _mm256_cmpgt_epi32(_mm256_set1_epi32((int)k5),
        _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7));
    __m128i ta = _mm_add_epi32(_mm256_castsi256_si128(_mm256_and_si256(tv, tm)),
                               _mm256_extracti128_si256(_mm256_and_si256(tv, tm), 1));
    ta = _mm_add_epi32(ta, _mm_shuffle_epi32(ta, _MM_SHUFFLE(1, 0, 3, 2)));
    ta = _mm_add_epi32(ta, _mm_shuffle_epi32(ta, _MM_SHUFFLE(2, 3, 0, 1)));
    s += (u32)_mm_cvtsi128_si32(ta);
  }
#else
  for (u32 j = 0; j < k5; j++) s += CT5[j];
#endif
  const __m256i ix=_mm256_setr_epi32(0,1,2,3,4,5,6,7);
  const __m128i iw=_mm_setr_epi16(0,1,2,3,4,5,6,7),ones=_mm_set1_epi16(1);
  auto wide=[&](const u32 *p,int k){return _mm256_and_si256(_mm256_loadu_si256((const __m256i*)p),_mm256_cmpgt_epi32(_mm256_set1_epi32(k),ix));};
  auto narrow=[&](const u16 *p,int k){return _mm_madd_epi16(_mm_and_si128(_mm_loadu_si128((const __m128i*)p),_mm_cmpgt_epi16(_mm_set1_epi16(k),iw)),ones);};
  const __m256i w=_mm256_add_epi32(wide(CT4+((v>>17)<<3),(v>>14)&7),wide(CT3+((v>>14)<<3),(v>>11)&7));
  __m128i h=_mm_add_epi32(_mm256_castsi256_si128(w),_mm256_extracti128_si256(w,1));
  h=_mm_add_epi32(h,narrow(CT2+((v>>11)<<3),(v>>8)&7));
  h=_mm_add_epi32(h,narrow(CT1+((v>>8)<<3),(v>>5)&7));
  h=_mm_add_epi32(h,_mm_shuffle_epi32(h,_MM_SHUFFLE(1,0,3,2)));
  h=_mm_add_epi32(h,_mm_shuffle_epi32(h,_MM_SHUFFLE(2,3,0,1)));
  s+=(u32)_mm_cvtsi128_si32(h)+su8_32(CT0+(v&~31u),(int)(v&31));
  return s;
}
#ifndef LFAUTO
#define LFAUTO 0
#endif
static int LFSH;
static int LFD;
static int LFB;   
static const u32 *XD[KG_MAXK];
static u32 *OUT;
static u64 *AB, *ABtop;

static inline int eid(u64 v) { return (int)(v & 0x3FFFFFu); }
static inline int lfbucket(u64 v) { return (int)(((u32)(v >> 65)) >> LFSH); }
static inline int eq_(u64 v) { return (int)((v >> 64) & 1); }
static inline int keep_test(int takeA, int role) { return 1 - (takeA ^ role); }
static inline u32 embnk(u64 v) { return (u32)((v >> 22) & 0x3FFFFFu); }
static inline u64 mk(u32 key, int q, int id, u32 nk) {
  return ((u64)key << 65) | ((u64)(1 - q) << 64) | ((u64)nk << 22) | (u64)id;
}

template <bool B> struct TB {};
template <int V> struct NCL { static const int v = (V < 0) ? 0 : ((V > 3) ? 3 : V); };
template <int KT, int D, int NO> static inline void solve_t(u64 *seq, int m, u64 *out);

static void ctr_solve(u64 *cross, int cx, u32 *dirt) {
  int nd = 0;
  for (int i = 0; i < cx; i++) {
#if MF_CTRPF > 0
    if (i + MF_CTRPF < cx) {
      u32 vf = (u32)(cross[i + MF_CTRPF] >> 65);
      __builtin_prefetch(&CT0[vf], 1, 0);
      __builtin_prefetch(&CT1[vf >> 5], 1, 0);
      __builtin_prefetch(&CT2[vf >> 8], 1, 0);
    }
#endif
    u64 v = cross[i];
    u32 val = (u32)(v >> 65);
    if ((v >> 64) & 1) { ctr_ins(val); dirt[nd++] = val; }
    else OUT[eid(v)] += ctr_qry(val);
  }
  for (int i = 0; i < nd; i++) {
#if MF_CTRPF > 0
    if (i + MF_CTRPF < nd) {
      u32 vf = dirt[i + MF_CTRPF];
      __builtin_prefetch(&CT0[vf], 1, 1);
      __builtin_prefetch(&CT1[vf >> 5], 1, 1);
      __builtin_prefetch(&CT2[vf >> 8], 1, 1);
    }
#endif
    const u32 v = dirt[i]; CT0[v]--; CT1[v >> 5]--; CT2[v >> 8]--;
  }
  /* [R132A-CTRR] 顶层三档退休. 每条插入在 ctr_ins 里对 CT3/CT4/CT5 各 +1,
     本循环原本逐元素各 -1 (3 次随机 RMW/元素) => 归零路径与元素数无关地等价:
     每次 ctr_ins 都有配对的清零 => 循环结束时三档【恰好回到进入本函数前的值】,
     而本函数进入前三档恒为 0 (静态 BSS 起零 + 每次调用净零, 归纳成立)
     => 用 3 次整域 memset 覆盖活跃跨度即可. 跨度按 counter_domain= 本次 n 取,
     未被使用的 padding 保持 0 不动. */
  if (nd) {
    memset(CT3, 0, ((size_t)(counter_domain + 2047) >> 11) * sizeof(u32));
    memset(CT4, 0, ((size_t)(counter_domain + 16383) >> 14) * sizeof(u32));
    memset(CT5, 0, ((size_t)(counter_domain + 131071) >> 17) * sizeof(u32));
  }
}

static const u32 VMASK[8][8] = {
  {0,0,0,0,0,0,0,0},
  {~0u,0,0,0,0,0,0,0},
  {~0u,~0u,0,0,0,0,0,0},
  {~0u,~0u,~0u,0,0,0,0,0},
  {~0u,~0u,~0u,~0u,0,0,0,0},
  {~0u,~0u,~0u,~0u,~0u,0,0,0},
  {~0u,~0u,~0u,~0u,~0u,~0u,0,0},
  {~0u,~0u,~0u,~0u,~0u,~0u,~0u,0}};
static inline u32 hsum256(__m256i v) {
  __m128i t = _mm_add_epi32(_mm256_castsi256_si128(v), _mm256_extracti128_si256(v, 1));
  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);
}
template<int ND>
static void base_case_t(u64 *seq, int m, int d, u64 *out, int needOut) {
  const int nd = ND;
  __attribute__((aligned(32)))
  u32 IK[KG_BASE + 8], IC0[KG_BASE + 8], IC1[KG_BASE + 8], IC2[KG_BASE + 8];
  u32 QK[KG_BASE + 8], QC0[KG_BASE + 8], QC1[KG_BASE + 8], QC2[KG_BASE + 8];
  u32 QID[KG_BASE + 8], QN[KG_BASE + 8];
  const u32 *X1 = (ND > 1) ? XD[d + 3] : 0, *X2 = (ND > 2) ? XD[d + 4] : 0;
  
#if LEAFNB
  static_assert(KG_BASE<65536,"leaf histogram must fit halfwords");
  const int NB=(LFAUTO && m<=LFB)?(m<8?8:m):LFB;
  u16 cnt[LEAFNB+2];
  if(needOut)for(int b=0;b<=NB;b++)cnt[b]=0;
#endif
  int ni = 0, nq = 0;
  for (int t = 0; t < m; t++) {
#if MF_LEAFLP > 0
    if ((ND > 1) && t + MF_LEAFLP < m) {
      int idf = eid(seq[t + MF_LEAFLP]);
      if (ND > 2) __builtin_prefetch(&X2[idf], 0, 1);
      __builtin_prefetch(&X1[idf], 0, 1);
    }
#endif
    u64 v = seq[t];
    int id = eid(v);
    u32 k = (u32)(v >> 65);
#if LEAFNB
    if(needOut)++cnt[(k>>(LFSH+LFD))+1];
#endif
    u32 c0 = 0, c1 = 0, c2 = 0;
    if (ND > 0) c0 = embnk(v);
    if (ND > 1) c1 = X1[id];
    if (ND > 2) c2 = X2[id];
    int isins = (int)((v >> 64) & 1u);
    IK[ni] = k; IC0[ni] = c0; IC1[ni] = c1; IC2[ni] = c2; ni += isins;
    QK[nq] = k; QC0[nq] = c0; QC1[nq] = c1; QC2[nq] = c2; QID[nq] = (u32)id; QN[nq] = (u32)ni; nq += 1 - isins;
  }
#if !defined(MF_G34_LDA)
#define MF_G34_LDA(p) _mm256_load_si256((const __m256i *)(p))
#define MF_G34_LDU(p) _mm256_loadu_si256((const __m256i *)(p))
#endif
#define LDA(p) MF_G34_LDA(p)
#define LDU_MASK(k) MF_G34_LDU((const __m256i *)VMASK[k])
  
#define K11B_TAIL(ACC, KVQ, C0Q, C1Q, C2Q, NX, JS) do {                                \
    int jj = (JS);                                                                     \
    for (; jj + 8 <= (NX); jj += 8) {                                                  \
      __m256i msk = _mm256_cmpgt_epi32(KVQ, LDA(IK + jj));                             \
      if (nd > 0) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(C0Q, LDA(IC0 + jj))); \
      if (nd > 1) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(C1Q, LDA(IC1 + jj))); \
      if (nd > 2) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(C2Q, LDA(IC2 + jj))); \
      ACC = _mm256_sub_epi32(ACC, msk);                                                \
    }                                                                                  \
    if (jj < (NX)) {                                                                   \
      int nn_ = (NX);                                                                  \
      __m256i msk = _mm256_cmpgt_epi32(KVQ, LDA(IK + jj));                             \
      if (nd > 0) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(C0Q, LDA(IC0 + jj))); \
      if (nd > 1) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(C1Q, LDA(IC1 + jj))); \
      if (nd > 2) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(C2Q, LDA(IC2 + jj))); \
      msk = _mm256_and_si256(msk, LDU_MASK(nn_ - jj));                                 \
      ACC = _mm256_sub_epi32(ACC, msk);                                                \
    }                                                                                  \
  } while (0)
  int q = 0;

#if MF_LEAFG >= 4
  
  if (nd <= 1) {
    for (; q + 4 <= nq; q += 4) {
      if (QN[q] > QN[q+1] || QN[q+1] > QN[q+2] || QN[q+2] > QN[q+3]) break;
      const int nA4 = (int)QN[q], nB4 = (int)QN[q+1], nC4 = (int)QN[q+2], nD4 = (int)QN[q+3];
      if (q + 12 + 4 <= nq) {
        __asm__ __volatile__("prefetchw %0" ::"m"(*(const char *)(&OUT[QID[q + 12]])));
        __asm__ __volatile__("prefetchw %0" ::"m"(*(const char *)(&OUT[QID[q + 13]])));
        __asm__ __volatile__("prefetchw %0" ::"m"(*(const char *)(&OUT[QID[q + 14]])));
        __asm__ __volatile__("prefetchw %0" ::"m"(*(const char *)(&OUT[QID[q + 15]])));
      }
      __m256i kA4 = _mm256_set1_epi32((int)QK[q]),   dA4 = _mm256_set1_epi32((int)QC0[q]),
              aA4 = _mm256_setzero_si256();
      __m256i kB4 = _mm256_set1_epi32((int)QK[q+1]), dB4 = _mm256_set1_epi32((int)QC0[q+1]),
              aB4 = _mm256_setzero_si256();
      __m256i kC4 = _mm256_set1_epi32((int)QK[q+2]), dC4 = _mm256_set1_epi32((int)QC0[q+2]),
              aC4 = _mm256_setzero_si256();
      __m256i kD4 = _mm256_set1_epi32((int)QK[q+3]), dD4 = _mm256_set1_epi32((int)QC0[q+3]),
              aD4 = _mm256_setzero_si256();
      int j4 = 0;
      for (; j4 + 8 <= nA4; j4 += 8) {                        
        __m256i IKv = LDA(IK + j4);
        __m256i mA = _mm256_cmpgt_epi32(kA4, IKv), mB = _mm256_cmpgt_epi32(kB4, IKv),
                mC = _mm256_cmpgt_epi32(kC4, IKv), mD = _mm256_cmpgt_epi32(kD4, IKv);
        if (nd > 0) {
          __m256i C0v = LDA(IC0 + j4);
          mA = _mm256_and_si256(mA, _mm256_cmpgt_epi32(dA4, C0v));
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(dB4, C0v));
          mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(dC4, C0v));
          mD = _mm256_and_si256(mD, _mm256_cmpgt_epi32(dD4, C0v));
        }
        aA4 = _mm256_sub_epi32(aA4, mA); aB4 = _mm256_sub_epi32(aB4, mB);
        aC4 = _mm256_sub_epi32(aC4, mC); aD4 = _mm256_sub_epi32(aD4, mD);
      }
      const int pA4 = j4;
      for (; j4 + 8 <= nB4; j4 += 8) {                        
        __m256i IKv = LDA(IK + j4);
        __m256i mB = _mm256_cmpgt_epi32(kB4, IKv), mC = _mm256_cmpgt_epi32(kC4, IKv),
                mD = _mm256_cmpgt_epi32(kD4, IKv);
        if (nd > 0) {
          __m256i C0v = LDA(IC0 + j4);
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(dB4, C0v));
          mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(dC4, C0v));
          mD = _mm256_and_si256(mD, _mm256_cmpgt_epi32(dD4, C0v));
        }
        aB4 = _mm256_sub_epi32(aB4, mB); aC4 = _mm256_sub_epi32(aC4, mC);
        aD4 = _mm256_sub_epi32(aD4, mD);
      }
      const int pB4 = j4;
      for (; j4 + 8 <= nC4; j4 += 8) {                        
        __m256i IKv = LDA(IK + j4);
        __m256i mC = _mm256_cmpgt_epi32(kC4, IKv), mD = _mm256_cmpgt_epi32(kD4, IKv);
        if (nd > 0) {
          __m256i C0v = LDA(IC0 + j4);
          mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(dC4, C0v));
          mD = _mm256_and_si256(mD, _mm256_cmpgt_epi32(dD4, C0v));
        }
        aC4 = _mm256_sub_epi32(aC4, mC); aD4 = _mm256_sub_epi32(aD4, mD);
      }
      const int pC4 = j4;
      for (; j4 + 8 <= nD4; j4 += 8) {                        
        __m256i mD = _mm256_cmpgt_epi32(kD4, LDA(IK + j4));
        if (nd > 0) mD = _mm256_and_si256(mD, _mm256_cmpgt_epi32(dD4, LDA(IC0 + j4)));
        aD4 = _mm256_sub_epi32(aD4, mD);
      }
      const int pD4 = j4;
      if(nD4-pA4<8){
        const __m256i ik=LDA(IK+pA4);
        __m256i mA=_mm256_cmpgt_epi32(kA4,ik);
        __m256i mB=_mm256_cmpgt_epi32(kB4,ik);
        __m256i mC=_mm256_cmpgt_epi32(kC4,ik);
        __m256i mD=_mm256_cmpgt_epi32(kD4,ik);
        if(nd>0){const __m256i v=LDA(IC0+pA4);
          mA=_mm256_and_si256(mA,_mm256_cmpgt_epi32(dA4,v));
          mB=_mm256_and_si256(mB,_mm256_cmpgt_epi32(dB4,v));
          mC=_mm256_and_si256(mC,_mm256_cmpgt_epi32(dC4,v));
          mD=_mm256_and_si256(mD,_mm256_cmpgt_epi32(dD4,v));
        }
        aA4=_mm256_sub_epi32(aA4,_mm256_and_si256(mA,LDU_MASK(nA4-pA4)));
        aB4=_mm256_sub_epi32(aB4,_mm256_and_si256(mB,LDU_MASK(nB4-pA4)));
        aC4=_mm256_sub_epi32(aC4,_mm256_and_si256(mC,LDU_MASK(nC4-pA4)));
        aD4=_mm256_sub_epi32(aD4,_mm256_and_si256(mD,LDU_MASK(nD4-pA4)));
      }else{
      K11B_TAIL(aA4, kA4, dA4, dA4, dA4, nA4, pA4);
      K11B_TAIL(aB4, kB4, dB4, dB4, dB4, nB4, pB4);
      K11B_TAIL(aC4, kC4, dC4, dC4, dC4, nC4, pC4);
      K11B_TAIL(aD4, kD4, dD4, dD4, dD4, nD4, pD4);
      }
      __m256i h0=_mm256_hadd_epi32(aA4,aB4),h1=_mm256_hadd_epi32(aC4,aD4);
      __m256i h=_mm256_hadd_epi32(h0,h1);
      __m128i sums=_mm_add_epi32(_mm256_castsi256_si128(h),_mm256_extracti128_si256(h,1));
      OUT[QID[q]]+=(u32)_mm_cvtsi128_si32(sums);
      OUT[QID[q+1]]+=(u32)_mm_extract_epi32(sums,1);
      OUT[QID[q+2]]+=(u32)_mm_extract_epi32(sums,2);
      OUT[QID[q+3]]+=(u32)_mm_extract_epi32(sums,3);
    }
  }
#endif

#if MF_LEAFG >= 3
  
  if (nd <= 2) {
    for (; q + 3 <= nq; q += 3) {
      if (QN[q] > QN[q + 1] || QN[q + 1] > QN[q + 2]) break;   
      const int nA3 = (int)QN[q], nB3 = (int)QN[q + 1], nC3 = (int)QN[q + 2];
      if (q + 16 <= nq) {
        __asm__ __volatile__("prefetchw %0" ::"m"(*(const char *)(&OUT[QID[q + 12]])));
        __asm__ __volatile__("prefetchw %0" ::"m"(*(const char *)(&OUT[QID[q + 13]])));
        __asm__ __volatile__("prefetchw %0" ::"m"(*(const char *)(&OUT[QID[q + 14]])));
      }
      __m256i kA3 = _mm256_set1_epi32((int)QK[q]),   dA3 = _mm256_set1_epi32((int)QC0[q]),
              eA3 = _mm256_set1_epi32((int)QC1[q]),  aA3 = _mm256_setzero_si256();
      __m256i kB3 = _mm256_set1_epi32((int)QK[q+1]), dB3 = _mm256_set1_epi32((int)QC0[q+1]),
              eB3 = _mm256_set1_epi32((int)QC1[q+1]), aB3 = _mm256_setzero_si256();
      __m256i kC3 = _mm256_set1_epi32((int)QK[q+2]), dC3 = _mm256_set1_epi32((int)QC0[q+2]),
              eC3 = _mm256_set1_epi32((int)QC1[q+2]), aC3 = _mm256_setzero_si256();
      int j3 = 0;
      for (; j3 + 8 <= nA3; j3 += 8) {                        
        __m256i IKv = LDA(IK + j3);
        __m256i mA = _mm256_cmpgt_epi32(kA3, IKv), mB = _mm256_cmpgt_epi32(kB3, IKv),
                mC = _mm256_cmpgt_epi32(kC3, IKv);
        if (nd > 0) {
          __m256i C0v = LDA(IC0 + j3);
          mA = _mm256_and_si256(mA, _mm256_cmpgt_epi32(dA3, C0v));
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(dB3, C0v));
          mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(dC3, C0v));
        }
        if (nd > 1) {
          __m256i C1v = LDA(IC1 + j3);
          mA = _mm256_and_si256(mA, _mm256_cmpgt_epi32(eA3, C1v));
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(eB3, C1v));
          mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(eC3, C1v));
        }
        aA3 = _mm256_sub_epi32(aA3, mA); aB3 = _mm256_sub_epi32(aB3, mB);
        aC3 = _mm256_sub_epi32(aC3, mC);
      }
      const int pA3 = j3;
      for (; j3 + 8 <= nB3; j3 += 8) {                        
        __m256i IKv = LDA(IK + j3);
        __m256i mB = _mm256_cmpgt_epi32(kB3, IKv), mC = _mm256_cmpgt_epi32(kC3, IKv);
        if (nd > 0) {
          __m256i C0v = LDA(IC0 + j3);
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(dB3, C0v));
          mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(dC3, C0v));
        }
        if (nd > 1) {
          __m256i C1v = LDA(IC1 + j3);
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(eB3, C1v));
          mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(eC3, C1v));
        }
        aB3 = _mm256_sub_epi32(aB3, mB); aC3 = _mm256_sub_epi32(aC3, mC);
      }
      const int pB3 = j3;
      for (; j3 + 8 <= nC3; j3 += 8) {                        
        __m256i IKv = LDA(IK + j3);
        __m256i mC = _mm256_cmpgt_epi32(kC3, IKv);
        if (nd > 0) mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(dC3, LDA(IC0 + j3)));
        if (nd > 1) mC = _mm256_and_si256(mC, _mm256_cmpgt_epi32(eC3, LDA(IC1 + j3)));
        aC3 = _mm256_sub_epi32(aC3, mC);
      }
      const int pC3 = j3;
      if(nC3-pA3<8){
        const __m256i ik=LDA(IK+pA3);
        __m256i mA=_mm256_cmpgt_epi32(kA3,ik);
        __m256i mB=_mm256_cmpgt_epi32(kB3,ik);
        __m256i mC=_mm256_cmpgt_epi32(kC3,ik);
        if(nd>0){const __m256i v=LDA(IC0+pA3);
          mA=_mm256_and_si256(mA,_mm256_cmpgt_epi32(dA3,v));
          mB=_mm256_and_si256(mB,_mm256_cmpgt_epi32(dB3,v));
          mC=_mm256_and_si256(mC,_mm256_cmpgt_epi32(dC3,v));
        }
        if(nd>1){const __m256i v=LDA(IC1+pA3);
          mA=_mm256_and_si256(mA,_mm256_cmpgt_epi32(eA3,v));
          mB=_mm256_and_si256(mB,_mm256_cmpgt_epi32(eB3,v));
          mC=_mm256_and_si256(mC,_mm256_cmpgt_epi32(eC3,v));
        }
        aA3=_mm256_sub_epi32(aA3,_mm256_and_si256(mA,LDU_MASK(nA3-pA3)));
        aB3=_mm256_sub_epi32(aB3,_mm256_and_si256(mB,LDU_MASK(nB3-pA3)));
        aC3=_mm256_sub_epi32(aC3,_mm256_and_si256(mC,LDU_MASK(nC3-pA3)));
      }else{
      K11B_TAIL(aA3, kA3, dA3, eA3, eA3, nA3, pA3);
      K11B_TAIL(aB3, kB3, dB3, eB3, eB3, nB3, pB3);
      K11B_TAIL(aC3, kC3, dC3, eC3, eC3, nC3, pC3);
      }
      __m256i h0=_mm256_hadd_epi32(aA3,aB3),h1=_mm256_hadd_epi32(aC3,aC3);
      __m256i h=_mm256_hadd_epi32(h0,h1);
      __m128i sums=_mm_add_epi32(_mm256_castsi256_si128(h),_mm256_extracti128_si256(h,1));
      OUT[QID[q]]+=(u32)_mm_cvtsi128_si32(sums);
      OUT[QID[q+1]]+=(u32)_mm_extract_epi32(sums,1);
      OUT[QID[q+2]]+=(u32)_mm_extract_epi32(sums,2);
    }
  }
#endif
#if MF_LEAFG >= 2
  
  for (; q + 2 <= nq; q += 2) {
    const int n = ((int)QN[q] < (int)QN[q + 1]) ? (int)QN[q] : (int)QN[q + 1];
    const int nA = (int)QN[q], nB = (int)QN[q + 1];
    __m256i kvA = _mm256_set1_epi32((int)QK[q]),     kvB = _mm256_set1_epi32((int)QK[q + 1]);
    __m256i v0A = _mm256_set1_epi32((int)QC0[q]),    v0B = _mm256_set1_epi32((int)QC0[q + 1]);
    __m256i v1A = _mm256_set1_epi32((int)QC1[q]),    v1B = _mm256_set1_epi32((int)QC1[q + 1]);
    __m256i v2A = _mm256_set1_epi32((int)QC2[q]),    v2B = _mm256_set1_epi32((int)QC2[q + 1]);
    __m256i accA = _mm256_setzero_si256(), accB = _mm256_setzero_si256();
    int j = 0;
    if (nd >= 3) {
      for (; j + 8 <= n; j += 8) {
        __m256i IKv = _mm256_load_si256((const __m256i *)(IK + j));
        __m256i C0v = _mm256_load_si256((const __m256i *)(IC0 + j));
        __m256i C1v = _mm256_load_si256((const __m256i *)(IC1 + j));
        __m256i C2v = _mm256_load_si256((const __m256i *)(IC2 + j));
        __m256i mA = _mm256_and_si256(_mm256_cmpgt_epi32(kvA, IKv), _mm256_cmpgt_epi32(v0A, C0v));
        __m256i mB = _mm256_and_si256(_mm256_cmpgt_epi32(kvB, IKv), _mm256_cmpgt_epi32(v0B, C0v));
        mA = _mm256_and_si256(mA, _mm256_cmpgt_epi32(v1A, C1v));
        mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(v1B, C1v));
        mA = _mm256_and_si256(mA, _mm256_cmpgt_epi32(v2A, C2v));
        mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(v2B, C2v));
        accA = _mm256_sub_epi32(accA, mA);
        accB = _mm256_sub_epi32(accB, mB);
      }
    } else {
      for (; j + 8 <= n; j += 8) {
        __m256i IKv = _mm256_load_si256((const __m256i *)(IK + j));
        __m256i mA = _mm256_cmpgt_epi32(kvA, IKv);
        __m256i mB = _mm256_cmpgt_epi32(kvB, IKv);
        if (nd > 0) {
          __m256i C0v = _mm256_load_si256((const __m256i *)(IC0 + j));
          mA = _mm256_and_si256(mA, _mm256_cmpgt_epi32(v0A, C0v));
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(v0B, C0v));
        }
        if (nd > 1) {
          __m256i C1v = _mm256_load_si256((const __m256i *)(IC1 + j));
          mA = _mm256_and_si256(mA, _mm256_cmpgt_epi32(v1A, C1v));
          mB = _mm256_and_si256(mB, _mm256_cmpgt_epi32(v1B, C1v));
        }
        accA = _mm256_sub_epi32(accA, mA);
        accB = _mm256_sub_epi32(accB, mB);
      }
    }
    
    {
      int jj = j;
      __m256i acc = accA;
      for (; jj + 8 <= nA; jj += 8) {
        __m256i msk = _mm256_cmpgt_epi32(kvA, _mm256_load_si256((const __m256i *)(IK + jj)));
        if (nd > 0) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0A, _mm256_load_si256((const __m256i *)(IC0 + jj))));
        if (nd > 1) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v1A, _mm256_load_si256((const __m256i *)(IC1 + jj))));
        if (nd > 2) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v2A, _mm256_load_si256((const __m256i *)(IC2 + jj))));
        acc = _mm256_sub_epi32(acc, msk);
      }
      if (jj < nA) {
        int n = nA;
        __m256i msk = _mm256_cmpgt_epi32(kvA, _mm256_load_si256((const __m256i *)(IK + jj)));
        if (nd > 0) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0A, _mm256_load_si256((const __m256i *)(IC0 + jj))));
        if (nd > 1) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v1A, _mm256_load_si256((const __m256i *)(IC1 + jj))));
        if (nd > 2) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v2A, _mm256_load_si256((const __m256i *)(IC2 + jj))));
        msk = _mm256_and_si256(msk, _mm256_loadu_si256((const __m256i *)VMASK[n - jj]));
        acc = _mm256_sub_epi32(acc, msk);
      }
      OUT[QID[q]] += hsum256(acc);
    }
    {
      int jj = j;
      __m256i acc = accB;
      for (; jj + 8 <= nB; jj += 8) {
        __m256i msk = _mm256_cmpgt_epi32(kvB, _mm256_load_si256((const __m256i *)(IK + jj)));
        if (nd > 0) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0B, _mm256_load_si256((const __m256i *)(IC0 + jj))));
        if (nd > 1) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v1B, _mm256_load_si256((const __m256i *)(IC1 + jj))));
        if (nd > 2) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v2B, _mm256_load_si256((const __m256i *)(IC2 + jj))));
        acc = _mm256_sub_epi32(acc, msk);
      }
      if (jj < nB) {
        int n = nB;
        __m256i msk = _mm256_cmpgt_epi32(kvB, _mm256_load_si256((const __m256i *)(IK + jj)));
        if (nd > 0) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0B, _mm256_load_si256((const __m256i *)(IC0 + jj))));
        if (nd > 1) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v1B, _mm256_load_si256((const __m256i *)(IC1 + jj))));
        if (nd > 2) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v2B, _mm256_load_si256((const __m256i *)(IC2 + jj))));
        msk = _mm256_and_si256(msk, _mm256_loadu_si256((const __m256i *)VMASK[n - jj]));
        acc = _mm256_sub_epi32(acc, msk);
      }
      OUT[QID[q + 1]] += hsum256(acc);
    }
  }
#endif
  for (; q < nq; q++) {
    const int n = (int)QN[q];
    __m256i kv = _mm256_set1_epi32((int)QK[q]);
    __m256i v0 = _mm256_set1_epi32((int)QC0[q]);
    __m256i v1 = _mm256_set1_epi32((int)QC1[q]);
    __m256i v2 = _mm256_set1_epi32((int)QC2[q]);
    __m256i acc = _mm256_setzero_si256();
    int j = 0;
    switch (nd) {
      case 0:
        for (; j + 8 <= n; j += 8)
          acc = _mm256_sub_epi32(acc, _mm256_cmpgt_epi32(kv, _mm256_load_si256((const __m256i *)(IK + j))));
        break;
      case 1:
        for (; j + 8 <= n; j += 8) {
      __m256i msk = _mm256_cmpgt_epi32(kv, _mm256_load_si256((const __m256i *)(IK + j)));
      msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0, _mm256_load_si256((const __m256i *)(IC0 + j))));
      acc = _mm256_sub_epi32(acc, msk);
        }
        break;
      case 2:
        for (; j + 8 <= n; j += 8) {
      __m256i msk = _mm256_cmpgt_epi32(kv, _mm256_load_si256((const __m256i *)(IK + j)));
      msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0, _mm256_load_si256((const __m256i *)(IC0 + j))));
      msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v1, _mm256_load_si256((const __m256i *)(IC1 + j))));
      acc = _mm256_sub_epi32(acc, msk);
        }
        break;
      default:
        for (; j + 8 <= n; j += 8) {
      __m256i msk = _mm256_cmpgt_epi32(kv, _mm256_load_si256((const __m256i *)(IK + j)));
      msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0, _mm256_load_si256((const __m256i *)(IC0 + j))));
      msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v1, _mm256_load_si256((const __m256i *)(IC1 + j))));
      msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v2, _mm256_load_si256((const __m256i *)(IC2 + j))));
      acc = _mm256_sub_epi32(acc, msk);
        }
        break;
    }
    if (j < n) {                                  
      __m256i msk = _mm256_cmpgt_epi32(kv, _mm256_load_si256((const __m256i *)(IK + j)));
      if (nd > 0) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v0, _mm256_load_si256((const __m256i *)(IC0 + j))));
      if (nd > 1) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v1, _mm256_load_si256((const __m256i *)(IC1 + j))));
      if (nd > 2) msk = _mm256_and_si256(msk, _mm256_cmpgt_epi32(v2, _mm256_load_si256((const __m256i *)(IC2 + j))));
      msk = _mm256_and_si256(msk, _mm256_loadu_si256((const __m256i *)VMASK[n - j]));
      acc = _mm256_sub_epi32(acc, msk);
    }
    u32 c = hsum256(acc);
    OUT[QID[q]] += c;
  }
  if (!needOut) return;
#if LEAFNB
  {
    unsigned sum=0;int b=0;
    for(;b+16<=NB+1;b+=16){
      __m256i v=_mm256_loadu_si256((const __m256i*)(cnt+b));
      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));
      __m256i lo=_mm256_permute2x128_si256(v,v,0x08);
      lo=_mm256_shuffle_epi8(lo,_mm256_set1_epi16(0x0f0e));
      v=_mm256_add_epi16(_mm256_add_epi16(v,lo),_mm256_set1_epi16((short)sum));
      _mm256_storeu_si256((__m256i*)(cnt+b),v);
      sum=(unsigned)_mm256_extract_epi16(v,15);
    }
    for(;b<=NB;b++){sum+=cnt[b];cnt[b]=(u16)sum;}
    for (int t = 0; t < m; t++) { u64 v = seq[t]; out[cnt[(int)(((u32)(v >> 65)) >> (LFSH + LFD))]++] = v; }
    int lo = 0;
    for (int b = 0; b < NB; b++) {
      int hi = (int)cnt[b];
      if (hi - lo > 1)
        for (int t = lo + 1; t < hi; t++) {
          u64 v = out[t];
          int q = t - 1;
          while (q >= lo && (unsigned long long)(v >> 64) < (unsigned long long)(out[q] >> 64)) { out[q + 1] = out[q]; q--; }
          out[q + 1] = v;
        }
      lo = hi;
    }
  }
#else
  for (int t = 1; t < m; t++) {
    u64 v = seq[t];
    int q = t - 1;
    while (q >= 0 && (unsigned long long)(v >> 64) < (unsigned long long)(seq[q] >> 64)) { seq[q + 1] = seq[q]; q--; }
    seq[q + 1] = v;
  }
  memcpy(out, seq, sizeof(u64) * (size_t)m);
#endif
}

#define MKE_CROSS(V, EMB) ((RK ? (((((V) >> 22) & 0x3FFFFFull) << 65) | ((V) & (((u64)1 << 64) | 0x3FFFFFull))) \
                               : ((V) & (((u64)1 << 64) | 0x3FFFFFull))) \
                           | (GAT ? ((u64)(EMB)[eid(V)] << 22) : 0ull))
#define MF_EMB_NONE 0
template<int NO, int RK, int GAT>
static inline void merge_loops(const u64 *retA, int h, const u64 *retB, int r,
                               u64 *out, u64 *cross, const u32 *XN, const u32 *XE, int &cx) {
  (void)XN;
  int ia = 0, ib = 0, t = 0;
  while (ia < h && ib < r) {
    __builtin_prefetch(retA + ia + 32);
    __builtin_prefetch(retB + ib + 32);
    if (NO) __builtin_prefetch(out + t + 32);
    __builtin_prefetch(cross + cx + 32);
    u64 ea = retA[ia], eb = retB[ib];
    int takeA = ((unsigned long long)(ea >> 64) < (unsigned long long)(eb >> 64));
    ia += takeA; ib += 1 - takeA;
    u64 v = takeA ? ea : eb;
    if (NO) out[t] = v;
    t++;
    int role = (int)((v >> 64) & 1);
    u64 c = MKE_CROSS(v, XE);
    cross[cx] = c;                       
    cx += keep_test(takeA, role);
  }
  while (ia < h) {
    u64 v = retA[ia++];
    if (NO) out[t] = v;
    t++;
    if ((v >> 64) & 1) cross[cx++] = MKE_CROSS(v, XE);
  }
  while (ib < r) {
    u64 v = retB[ib++];
    if (NO) out[t] = v;
    t++;
    if (!((v >> 64) & 1)) cross[cx++] = MKE_CROSS(v, XE);
  }
}

template <int KT, int D, int NO>
static void solve_b(u64 *seq, int m, u64 *out, TB<true>) {
  (void)out;
  int cnt = 0;
  for (int t = 0; t < m; t++) {
    u64 v = seq[t];
    if ((v >> 64) & 1) cnt++;                       
    else OUT[eid(v)] += (u32)cnt;                   
  }
}

template <int KT, int D, int NO>
static void solve_b(u64 *seq, int m, u64 *out, TB<false>) {
  if (m <= KG_BASE) {
    base_case_t<NCL< KT - (D + 2) >::v>(seq, m, D, out, NO);
    return;
  }
  int h = m >> 1, r = m - h;
  u64 *save = ABtop;
  u64 *retA = ABtop; ABtop += h;
  u64 *retB = ABtop; ABtop += r;
  solve_t<KT, D, 1>(seq, h, retA);
  solve_t<KT, D, 1>(seq + h, r, retB);
  u64 *cross = ABtop; ABtop += m + 1;
  const int RK = (D + 2 <= KT - 1) ? 1 : 0;         
  const int GAT = (D + 3 <= KT - 1) ? 1 : 0;        
  const u32 *XN = RK ? XD[D + 2] : 0;               
  
  const u32 *XE = GAT ? XD[D + 3] : 0;
  int cx = 0;                      
  merge_loops<NO, RK, GAT>(retA, h, retB, r, out, cross, XN, XE, cx);
  if (FUSE_OK && D == KT - 3) {
    u32 *dirt = (u32 *)ABtop; ABtop += (cx + 3) / 2 + 1;
    ctr_solve(cross, cx, dirt);
  } else {
    solve_t<KT, D + 1, 0>(cross, cx, nullptr);
  }
  ABtop = save;
}

template <int KT, int D, int NO>
static inline void solve_t(u64 *seq, int m, u64 *out) {
  if (m <= 1) return;
  solve_b<KT, D, NO>(seq, m, out, TB<(D >= KT - 1)>());
}

#ifndef MF_S0P
#define MF_S0P 16
#endif
static u32 *g_ord, *g_x;

static void sort0(int n) {
  const u32 *X0 = XD[0];
  u32 *cnt = g_x;
  /* [R132A-HIST8] 第一轴计数表 u32 -> u8. 死事件竞技场 AB 在 sort0 期间未被使用
     (run_t: ABtop=AB -> FNV probe -> sort0 -> ev=AB, 见下) => 直接借用, 零额外静态内存.
     精确终population 证明无字节回绕: 若任一桶 >255, u8 回绕使 sum==n-256k != n
     => 走 u32 重建原路. 桶大小 ~1 (坐标 [0,n) 随机) => 生产上兜底从不触发. */
  u8 *hist = reinterpret_cast<u8 *>(AB);
  memset(hist, 0, (size_t)n + 1);
  for (int i = 0; i < n; i++) {
    // [R132A-S0P] 计数趟随机 RMW 的写意图前瞻(我方在册机理, 见件头引用)
    if (i + MF_S0P < n) {
      u32 vf = X0[i + MF_S0P];
      __asm__ __volatile__("prefetchw %0" :: "m"(*(const char *)(&hist[vf + 1])));
    }
    ++hist[X0[i] + 1];
  }
  u32 sum = 0;
  for (int v = 0; v <= n; v++) { sum += hist[v]; cnt[v] = sum; }
  if (sum != (u32)n) {
    memset(cnt, 0, sizeof(u32) * (size_t)(n + 1));
    for (int i = 0; i < n; i++) cnt[X0[i] + 1]++;
    for (int i = 0; i < n; i++) cnt[i + 1] += cnt[i];
  }
  for (int i = 0; i < n; i++) {
    if (i + MF_S0P < n) {
      u32 vf = X0[i + MF_S0P];
      __builtin_prefetch(&cnt[vf], 0, 3);
      __asm__ __volatile__("prefetchw %0" :: "m"(*(const char *)(&g_ord[cnt[vf]])));
    }
    g_ord[cnt[X0[i]]++] = (u32)i;
  }
}

template <int KT>
static void run_t(int n, const u32 **x, u32 *out) {
  LFSH = 0; LFD = 0;
  for (int d = 0; d < KT; d++) XD[d] = x[d];
  OUT = out;
  ABtop = AB;
  if (n <= 1) return;
  FUSE_OK = 0;
  counter_domain = (u32)n;
  if (KT >= 4 && n > 2 && (u32)n < CT_MAXV) {
    const u32 *XL = XD[KT - 1];
    memset(CT0, 0, (size_t)n);
    int ok = 1;
    for (int i = 0; i < n; i++) if (++CT0[XL[i]] > 127) { ok = 0; break; }
    memset(CT0, 0, (size_t)n);
    FUSE_OK = ok;
  }
  {
    int bit = 0;
    while ((n >> bit) >= LEAFNB && bit < 30) bit++;
    LFSH = bit; LFD = 0;
    LFB = (int)((((u32)(n - 1)) >> (LFSH + LFD)) + 2u);   
    if (LFB > LEAFNB) LFB = LEAFNB;
    if (LFB < 8) LFB = 8;
  }
  sort0(n);
  const u32 *X0 = XD[0], *X1 = XD[1];
  const u32 *nk2 = (KT >= 3) ? XD[2] : X0;   
  u64 *ev = AB;                     
  int m = 0, g = 0;
  while (g < n) {
    int g1 = g;
    u32 v = X0[g_ord[g]];
    while (g1 < n && X0[g_ord[g1]] == v) g1++;
    const int group_size = g1 - g;
    for (int t = g; t < g1; t++) {
      if (t + 16 < g1) { u32 idf = g_ord[t + 16]; __builtin_prefetch(&X1[idf], 0, 1); __builtin_prefetch(&nk2[idf], 0, 1); }
      const u32 id = g_ord[t];
      const u64 event = mk(X1[id], 1, (int)id, nk2[id]);
      ev[m] = event;
      ev[m + group_size] = event | ((u64)1 << 64);
      ++m;
    }
    m += group_size;
    g = g1;
  }
  ABtop = AB + m;
  solve_t<KT, 0, 0>(ev, m, nullptr);
}

}  

static u64 g_arena[KG_ARENA];
static u32 g_ord_st[4194308], g_x_st[4194308];
static int g_ready = 0;

static void setup() {
  if (g_ready) return;
  g_ready = 1;
  kg::AB = g_arena;
  kg::g_ord = g_ord_st;
  kg::g_x = g_x_st;
}

void count_4d(int n, const unsigned *x[4], unsigned *out) {
  setup();
  memset(out, 0, sizeof(unsigned) * (size_t)n);
  kg::run_t<4>(n, (const unsigned **)x, out);
}
#pragma GCC pop_options

CompilationN/AN/ACompile OKScore: N/A

Testcase #16.313 s406 MB + 540 KBAcceptedScore: 100


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