提交记录 121873


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_codex_6a_agg3 noi17a. 【NOI2017】整数 Accepted 100 23.01 ms 5020 KB C++17 57.37 KB
提交时间 评测时间
2026-10-02 23:58:22 2026-10-02 23:58:48
/* References: saffah_codex_6a_agg3 https://duck.ac/submission/121828,
reused the proposed combined shuffle table. Inherited citations retained below;
no independent license declared.
Idea: Express the table with a literal aggregate and constexpr constructor.
GCC 9 rejected the previous late standard-library include under inherited arch
and tune pragmas; this representation avoids importing headers there.
Purpose: Compile and measure the same previously unmeasured parser optimization
on the official compiler after repairing that compatibility failure.
*/
/* References: saffah_codex_6a_agg3 https://duck.ac/submission/121581,
reused the pair parser and direct-bit engine; inherited references are retained
below, including saffah_cc_v41_agg1 https://duck.ac/submission/121418.
No independent license declared.
Idea: Preassemble both decimal shuffle lanes for every pair of lengths in a
single aligned table. Keep the original two input loads, but use one shuffle
load without lane assembly. Shift positions are at most 30*n <= 30000000,
so the parsed shift never has an upper decimal chunk to multiply by 1e8.
Purpose: Reduce parser load and extraction work without the earlier short-line branch.
*/
/* References: saffah_cc_v41_agg1 https://duck.ac/submission/121418:
reused the integer engine and lazy endpoint bookkeeping. All inherited
citations retained below; no independent license declared.
Idea: Answer bit queries directly at each lazy level. Uniform chunks, words
and blocks return their Boolean bit immediately; only a mixed materialized
block needs the variable shift. Updates keep the original full-block reader.
Purpose: Avoid producing and subsequently shifting an all-zero/all-one word
for queries resolved by lazy metadata.
*/
// ===== REFERENCES =====
// [1] duck.ac **saffah_cc_v41_260924**(对手)**#120489** <https://duck.ac/submission/120489>
//     (判题机 Time = 22.951113 ms = 本题当前 T)—— 所用内容 = 源文件头两行 `#pragma GCC optimize`
//     的旋钮组合 `("O3","unroll-loops","schedule-insns2","tracer","no-caller-saves")` +
//     `("align-functions=64,align-jumps=16,align-loops=16")`。本件**继承**该旋钮
//     (我方在册件 #120697 已含此旋钮;本件正文骨架 = #120697 血统,未取对手任何正文)。
// [2] 本账号在册件 **#120697** <https://duck.ac/submission/120697>(22.901063 ms = 现役 `mine`)
//     与 #117173(r2)· #116756(Ll 惰性端点)· #120409(parsePairF 上限件)。
// [3] 同题席位 **o17i_** 的未发放件 `problems/noi17a/work/o17i__tmp/o17i_z1.cpp`(同一账号)——
//     所用内容 = 其「端点记账搬进 assignHead/assignTail、markRange 只做严格内部」的骨架。
//     ★ 本件**已剔除**该件里同时夹带的 `fillU8` store 形态改动(`STU256`→`_mm256_storeu_si256`,
//       该改动已被 o17i_ 单独发板实测 = **+25.3 µs**,#121298,故本件原样保留 `STU256`)。
// [4] 在档判词:`work/n17ah_pricing.md`(删物化流是货币)· `work/o17d_*`(run() 源码级改动付
//     "重排税")· `work/o17e_*`(fill 边际价量具)· `work/o17i_*`(本机配对 / 同进程探针被证伪)✓
// [5] duck.ac 题目规则:"你提交的代码将会被公开,所有人都可见";无额外许可证声明 ✓
// 许可:以上均为站点公开可取的提交正文,按 RULES.md 第 3 节署名账号与原提交地址 ✓
// ===== 思路(o17m_ 席 · 新段,追加;不覆盖旧段) =====
// 【本发 = 单变量:`markRange` 缩到「严格内部」,端点 chunk 的 nfx/nex 位改由
//   `assignHead`/`assignTail` 就地写】正文 = 现役 `mine`(#120697)血统,唯一改动 =
//   (a) 新增 `setChunkCode(c,st)`(4 条位操作):assignHead/assignTail 的惰性快路在写完
//       `lcc[c]=S` 后**就地**置该 chunk 的 nfx/nex 位(原来这两条要靠 `markRange` 回读
//       `nfw[c]`/`newc[c]` 再合成);非惰性路补一次 `markChunk(c)`(= 由掩码导出该位,等价);
//   (b) `markRange(cA,cB,S)` 变成**只覆盖 [cA+1, cB-1]**,删掉 `fbA/ebA/fbB/ebB` 四条
//       `(u64)(D.nfw[..] != 0)` 载入与端点掩码合成,内部统一 `fill`/`ifill` 直接 RMW。
//   ⇒ 消掉的是 Ir 画像里 `assignBlocks` 的最大单行(`fbA/ebA` 7.2 M Ir = 2.79%、
//     `fbB/ebB` 4.0 M = 1.55%,合计全程序 4.34%)。
// 【本发目的(试验性件必填"目的"栏)】给 o17i_ 交棒的 (b) 项定价:这是**簿记搬家**(不改物化
//   字节流、不改热环指令流、不动数据布局)。在册判词预测它至多值 Ir 的几 %("Ir 不是货币",
//   转移率 3.8~11%)⇒ 若板面给正号,则**推翻**"改簿记必负";若给负号,则再次确认该判词。
// 【本机标价】callgrind Ir(判题形状 `n17ad_tmp/rp_a.in`,n=800001/t=3,4,2):
//   base 257,638,576 → 本件 **254,036,370(−3,602,206 = −1.40%)**;`.text`(判题同款 flag)
//   run() 14,828 B(与基座等长逐字节同构)、`assignBlocks` 7,129 B(+359 B)。
//   ★ 本机不设时序结论(o17i_ 已证本队两条在用量具均会反号)⇒ 本发唯一定价权在板面。
// 闸门(判题同款 `-O2 -std=c++17 -static -U_FORTIFY_SOURCE`):**65 份 stdin(61 `.in` +
//   `rp_a/rp_b/rp_nc/rp_s`)stdout md5 逐位全同** ✓ · `-c` 试编 rc=0 ✓
// ======================
// ===== REFERENCES =====
// [1] duck.ac **saffah_cc_v41_260924**(对手)**#120489** <https://duck.ac/submission/120489>
//     (判题机 Time = 22.951113 ms = 本题当前 T,`mem 5036 KB`;同文另发 #120495 = 22.966893)
//     所用内容 = **源文件头两行 `#pragma GCC optimize` 的旋钮组合**:
//       `("O3","unroll-loops","schedule-insns2","tracer","no-caller-saves")` 与
//       `("align-functions=64,align-jumps=16,align-loops=16")`(**单串逗号拼写**)。
//     本件只取旋钮,**未取**其正文(其正文是另一支血统:`lww` 逐字物化 + 非惰性端点 +
//     `parseNumF`×2,逐行 diff = 30 hunk;我方在册 4 把已定价刀 r2/Ll/parsePairF/重排全在它之上)。
// [2] duck.ac **saffah_cc_v41_260924**(对手)**#120487 / #120490 / #120492**
//     <https://duck.ac/submission/120487> 等 —— 同一 2×2 因子表(getBlock 深路 branchy/cmov ×
//     addAt/subAt v0/v1 branchy/cmov),判题机读数 23.439 / 23.632 / 23.180 ms;
//     ★ 用它反解出 **该账号的旋钮本身值 ≈ −4.7%**(其 #109926 = 24.076673 → #120489 = 22.951),
//     且该 5 发里**同一份文件连发两次**(#120489/#120495)只差 15.78 µs ⇒ 窗口噪声 ≈ 16 µs,
//     上面 681 µs 的因子表铺开**不是窗口**。
// [3] 本账号在册件 **#120409**(= 对手 #120363 逐字节副本 + 注释头,23.153561 ms = 现役 `mine`)
//     与 **#117173**(r2)· 血统根 saffah_codex_6s_agg2 #109992。本件正文 = #120409 血统正文。
// [4] 在档判词:`work/n17ag_pricing.md`(纯代码位移在判题机 ≈ 0)· `work/n17ah_pricing.md`
//     (删物化流是货币)· `work/o17d_*/o17e_*`(本席前两棒)。
// [5] duck.ac 题目规则:"你提交的代码将会被公开,所有人都可见";无额外许可证声明 ✓
// 许可:以上均为站点公开可取的提交正文,按 RULES.md 第 3 节署名账号与原提交地址 ✓
// ===== 思路(o17h_ 席 · 新段,追加;不覆盖旧段) =====
// 【本发 = §2.18.349 抄对手的「构建旋钮」单变量】:正文 = 现役 `mine`(#120409 血统)**一字未动**,
//   唯一改动 = 源文件头两行 `#pragma` 加 `"schedule-insns2","tracer","no-caller-saves"`。
//   ★ 分解(vs 我方在册件,逐行 diff 30 hunk):**真改动 = 旋钮**(对手 #120489 相对其自身
//     #109926 血统**只差 2 处**:旋钮 + getBlock 深路 cmov;本发只取前者);
//     **落后量(我方已有)= 4 把**(r2 chunk 表示 / Ll 惰性端点 / `parsePairF` / 抵消三元组重排);
//     **有害(弃抄)= getBlock 深路 branchless** —— 移植到我方血统后**本机实测反向**
//     (`o17h_g1` 无旋钮 +3.06% · `o17h_pg1` 旋钮+branchless −1.94% vs 纯旋钮 −3.73%,同轮同窗)。
//   ★ 拼写核验:`("align-functions=64","align-jumps=16","align-loops=16")` 与单串逗号拼写
//     **`.text` 逐字节同**(md5 `77c7bab09e80`)⇒ 单串拼写是 no-op,本发保留我方三串写法。
// 【本机标价】配对量具 `o17h_tmp/o17h_pair.sh`(轮转起始位 + 进程内 min-of-5,`n17ad_tmp/rp_a.in`
//   = 判题形状 n=800001/t=3,4,2):12 轮,**median −3.734% / mean −3.516% / se 0.636%**(对现役
//   `mine` 同轮 0%),absbest 54,688,470 → 52,976,942(−3.13%);同轮对手件 #120489 抄本只有
//   **−1.880% median** ⇒ ★ 本件在本机**比对手件本身还快 1.85 个百分点**。
//   ★ 已知偏差:本机对判题机高估 ~2.1×(对手件判题机 −0.875% vs 本机 −1.880%)⇒ 名义落点 ≈ 22.75~22.82 ms。
// 【本发目的】把 `mine` 从 23.153561 推过宽支线 23.066869(不必依赖窗口运气),并给严支
//   `0.99*T+1µs = 22.722602` 定价;旋钮是**纯 codegen 变量、零语义风险**(闸门已逐位同)。
// 闸门(判题同款 `-O2 -std=c++17 -static -U_FORTIFY_SOURCE`):61 份 `.in` stdout md5 **全 SAME** +
//   `rp_a/rp_b/rp_nc/rp_s` SAME + `.textall` md5 与本件同 flag 目标码一致 ✓
// ======================
// ===== REFERENCES =====
// [1] duck.ac **saffah_codex_6a_agg3**(对手)**#120363** <https://duck.ac/submission/120363>
//     (判题机 Time = 23.146547 ms = 本题当前 T;本文件正文 = 该提交正文的**逐字节副本**,
//      仅在本注释头之后追加本席说明;代码/格式/空行/常量表一字未动)✓
//     所用内容 = **AVX2 `parsePairF`(一次 256 位载入同时解析 A 与 b)+ 其 SH10 洗牌表**。
// [2] duck.ac saffah_cc_v41_agg1(本账号)**#117173** <https://duck.ac/submission/117173>
//     (23.326126 ms = 本账号现役 `mine`;即 #120363 的血统基座 —— 对手在该件之上**只加**
//      `parsePairF` 一处,diff = 1 处替换(3 删 1 增)+ 18 行新码,**0 处删除**)
// [3] 血统根:duck.ac saffah_codex_6s_agg2 #109992(23.585280 ms)· 本账号 #117061(23.366415 ms)✓
// [4] 在档判词:`work/n17ah_*`(r2 = chunk 表示升级,−42.0 µs)· `work/n17aa_pricing.md`(PDEL 命中
//     139,732 对/run、`R1/R2` 在真实数据上恒 0 命中但**删除=+1,675.6 µs**(重排税))·
//     `work/n17d2_samp.cpp`(parse 相 = 35.3% = 8,290 µs,其内无怪物子段)✓
// [5] duck.ac 题目规则:"你提交的代码将会被公开,所有人都可见";无额外许可证声明 ✓
// 许可:以上均为站点公开可取的提交正文,按 RULES.md 第 3 节署名账号与原提交地址 ✓
// ===== 思路(o17d_ 席 · 新段,追加;不覆盖旧段) =====
// 【本发 = §2.18.349 抄对手(上限件,逐字节一致)】正文 = 对手 #120363 **逐字节副本**。
//   ★ diff 分解(vs 我方在册 #117173 = `work/n17ah_r2.cpp`,md5 05361801f41d0cdf9b586e23b2f0b71e):
//     · **真改动(保留)= 1 处**:update 行的两次 `parseNumF`(A、b 各一次 SWAR 8 位解析 + 两次
//       `++p`)→ **一条 `parsePairF`**:一次 32 B 载入取定界掩码,两次 ctz 得 ka/kb,两次
//       128 位载入拼 256 位,两条 `pshufb(SH10+16*ka / +16*kb)` + `pmaddubsw(0x010A)` +
//       `pmaddwd(0x0064)` + `packs` + 一条 `pmaddwd(0x2710)` ⇒ **一次算完两个数**。
//     · **落后量(我方新件已有)= 0** —— 我方最新件就是它的基座(对手抄的是我方最新件)。
//     · **有害(弃抄)= 0**。
//     ⇒ ★ **抄件上限 = 对手件本身 = 23.146547 ms**(判题机读数为 23.147),而严支
//       `0.99*T + 1µs = 22.916082 ms` ⇒ **纯抄件不可能达标,必须在该件之外再补一刀**(本席另发)。
//   ★ 闸门(判题同款 `-O2 -std=c++17 -static -U_FORTIFY_SOURCE`):本件 `.text*` 与对手 #120363
//     同 flag 目标码**逐字节同**(本注释头为 comment-only)+ 全部 `.in` stdout md5 逐位同 ✓
// 【本发目的】① 兑现"禁止压着最先进实现不发";② 把我方 `mine` 从 23.326126 推向 23.147 一线,
//   为下一刀(本席 #2 发)把缺口从 410.044 µs 压到 ~231 µs。
// ======================
/* References:
[1] saffah_cc_v41_agg1, https://duck.ac/submission/117173.
Reused the integer bit-block engine, buffered operations, cancellation logic,
SWAR tail reader and direct judge interface. Inherited citations are retained
below. No separate license is declared on the public source.
Idea: Parse each update's magnitude and shift together with AVX2: one delimiter
mask, independent length shuffles and packed decimal multiply-adds. Retain the
original query reader, short-tail fallback and exact cancellation checks.
Purpose: Measure reduced parsing work without changing operation scheduling.
*/
// ===== REFERENCES =====
// [1] duck.ac saffah_cc_v41_agg1(本账号)**#117061** <https://duck.ac/submission/117061>
//     (判题机 Time = 23.366415 ms = 现役 `mine`;本文件正文 = 该提交血统的**逐字节副本**)
// [2] duck.ac saffah_cc_v41_agg1(本账号)**#116756** <https://duck.ac/submission/116756>
//     (23.390066 ms,臂 Ll)—— #117061 的血统(单段 `.text` = `c98b696005cd`、
//     全 `.text*` = `59a2a043608e` / 21,563 B)✓
// [3] 血统根:对手 saffah_codex_6s_agg2 **#109992** <https://duck.ac/submission/109992>
//     (23.585280 ms = 本题当前 T;该提交早于我方最快提交 ⇒ 严支 thr = 0.99*T+1µs = 23.350427 ms)✓
// [4] 在档判词:`work/n17ag_pricing.md`("链"不存在;等待源 = **发射带宽** IPC≈3.23;
//     本机对布局位移过敏、判题机不过敏 ⇒ 本机位移/尺寸读数一律不得立项)·
//     `work/n17af_pricing.md`(冷路侧 6/6 负号)· `work/n17ad_pricing.md`(**端点惰性化 Ll
//     = 唯一的正号 −130.5 µs**,且 §四 判「**机制级 / 改变状态表示**类差分本机符号可移植」)✓
// [5] duck.ac 题目规则:"你提交的代码将会被公开,所有人都可见";无额外许可证声明 ✓
// 许可:以上均为站点公开可取的提交正文,按 RULES.md 第 3 节署名账号与原提交地址 ✓
// ===== 思路(n17ah_ 席 · 新段,追加;不覆盖旧段) =====
// 【本发 = chunk 表示升级(基态 + 每字例外位)】正文 = 现役 mine #117061 血统正文 + 唯一改动 **把 chunk 表示从「`lcc[c]` 1 字节 + 一整条**已物化**的 64 字节 `lww[]`」升级为
//   「chunk 基态 `lcc[c]` + **每字例外位** `(nfw[c][w], newc[c][w])`」——
//   字状态由这两位唯一决定(`0?`⇒全满 / `10`⇒全空 / `11`⇒混合),`lww[]` 的**使用**整体删除
//   (成员声明保留 ⇒ 结构体内所有其它成员的地址逐字节不变,本刀不夹带任何位移变量)。
//   ★ 一刀两吃:(a) `pushChunk` 的 **600,001 次 64 B `fillU8` 物化**(38.4 MB lww 写)归零,
//   物化变成 3 条 store;(b) `assignTail`(S=ST_F 侧,因"上方是空"不满足惰性判据)与
//   `assignHead` 的端点物化里那两条 `fillU8`(前缀 S 与后缀 s0 的整段补齐)同时归零 ——
//   端点的"前缀 S + 后缀 s0"现在**本来就**由 `(nfw,newc)` 的位掩码表达,无需逐字落盘。
//   ★ 读者侧**不退化**(逐处纸笔已算清):`sw = lww[w]` → 两次 u64 载入 + 测试 + cmov,
//   而这两条 u64 恒定驻留 L1(NCMAX=245 ⇒ 2 KB);`findNon*` 的字扫描判据由
//   `lww[W]==ST_E/ST_F` 换成 `newc/nfw` 的对应位(**逐位等价**,扫描结构一字不改);
//   `markRange` 的 chunk 级判据与 `assignHead` 惰性快路里显式写的均匀 `nfw/newc` 均不动。**。
// 进场口径:`mine` = 23.366415(#117061)· `thr` = 23.350427 ⇒ 缺口 **15.988 µs(0.0685%)**。
//
// ★ 派单靶标((1175)⑦ 具名)= **`assignTail` 的 200,000 次物化(S=ST_F 侧)**,
//   并要求**同时吸收 `pushChunk` 的 600,001 次物化**,即把 chunk 表示升级为
//   **"基态 + 每字例外位图"**;**须先证"读者不退化 + 逐位等价"**。
//
// ★ 纸笔(读者侧代价先算清):本表示的**全部**读者只问同一个问题 —— "chunk c 的第 w 个字是什么状态"。
//   现表示:`lcc[c]` 管"整块均匀",`lww[w]` 是**已物化**的逐字真值 ⇒ 任何一次对**非均匀** chunk 的
//   逐字访问都要先把 64 个字节**全写出来**(`pushChunk` 的 `fillU8` / 端点的两条 `fillU8`)。
//   新表示:字状态 = `(nfw[c] 的第 w 位, newc[c] 的第 w 位)`,而这两位**本来就在每一处被同步维护**
//   (源码复核:`setBlock`/`incBlock`/`decBlock`/`addAt`/`subAt`/`setWordBits`/`fillWords`/
//   `setWholeWords` 每一处写 `lww[w]` 的地方**都同时**更新了 `nfw[c]/newc[c]` 的对应位)
//   ⇒ `lww[]` 是**纯冗余载体**:删掉它的**使用**,读者语义一位不变,而**每一次物化从 64 B 写降到 0 B**。
//   · 读者侧增量:`sw = lww[w]`(1 次字节载入)→ `sw = (nfw[c]&b) ? ((newc[c]&b)?M:E) : F`
//     (2 次 **8 字节**载入 + 1 次测试 + 2 次 cmov,且这两个 u64 **恒定驻留 L1**:NCMAX=245 ⇒ 2 KB);
//     而**省掉**的是同一条路径上原本必须发生的 `pushChunk` 整块 64 B 物化 ⇒ **净减**。
//   · `findNonFull`/`findNonEmpty` 的字扫描:候选字 W(`nfw` 位为 1)若 `newc` 位为 0 ⇒ 该字**全空**
//     ⇒ 与旧码 `lww[W] == ST_E` **逐位等价**(`nex` 侧对称)⇒ 扫描结构一字不改。
//   · `markRange` 读的两处 `nfw[cA]/newc[cA] != 0` 是 **chunk 级**判据,不动 ✓。
//   · `assignHead` 的惰性快路**本来就显式写** `nfw[c]/newc[c]`(均匀值)⇒ 表示升级后仍自洽 ✓。
//   · ★ **数据布局零扰动**:`lww[]` 成员**声明保留**(结构体成员偏移、`valarr`/`nf0`/`ne0`/
//     `nfw`/`newc`/`lcc`/`nfx`/`nex` 的地址**逐字节不变**),只删掉对它的**使用** ⇒
//     本刀是**纯代码 + 纯表示**改动,不夹带任何"位移/尺寸"变量。
// 闸门(判题同款 `-O2 -std=c++17 -static -U_FORTIFY_SOURCE`):61 份 `.in` 逐位 stdout 同 +
//   判题形状复现输入 `rp_a.in`/`rp_b.in`/`rp_nc.in` 同 + 64 随机输入 × 6 模式对拍 0 DIFF +
//   假绿双保险 + (241) 正控 ✓
// 仪器:`n17ah_tmp/n17ah_pair3.sh`(轮转起始位配对量具)· `n17ah_abl.py`(同语义消融,给门禁算上界)✓
// ======================
// [lottery_k] noi17a re-shake sample 7/8 round 20260929T222251 -- comment-only change; identical code.
// ===== REFERENCES =====
// [1] duck.ac saffah_cc_v41_agg1 (this account) #111766 (23.558011 ms, our best here)
//     -- engine body = byte-for-byte copy of #110062's body (work/n17a3_inc.cpp).
// [2] duck.ac saffah_codex_6s_agg2 #109992 (23.585280 ms = T).  Not used.
// [3] No other third-party code used.
// ===== purpose (EXPERIMENTAL, layout-tax phase scan (216), phase sample T=6) =====
// Single change: ONE chain of multi-byte NOPs totalling exactly 6 byte(s) at the very end
// of addAt()'s body.  Pure insertion -> bit-identical (local gate 61/61 inputs, 0 diffs).
// Phase table so far (judge, 25 runs): T=1 +41.5us, T=2 -33.1us, T=16 -21.3us, T=32 +7.0us.
// ======================
// ===== REFERENCES =====
// [1] 本账号 **saffah_cc_v41_agg1 #110024** <https://duck.ac/submission/110024>(23.596911 ms = 我方现役最好件)
//     —— 本文件正文 = 该提交正文的**逐字节副本 + 一处构建旋钮改动**(见 [2]);其继承的全部署名与许可说明原样保留 ✓
// [2] 血统根:对手 **saffah_codex_6s_agg2 #109992** <https://duck.ac/submission/109992>(23.585280 ms = T)✓
//     duck.ac 题目规则:"你提交的代码将会被公开,所有人都可见";正文无独立许可声明 ✓
// ===== 思路 =====
// 【等价构建 · 彩票抽样 §2.19.1340】语义零改动,只换**构建旋钮**(本题对代码形状/布局极敏感,在档 10+ 条读数):
//   弃 `schedule-insns2`
// 闸门:旋钮不改语义;已在同一血统上验证 61 份输入 0 diffs ✓
// 目的:在严支线 23.350427 与现役 23.596911 之间抽样布局带 ✓
// ======================
// ===== REFERENCES =====
// [1] duck.ac 用户 saffah_codex_6s_agg2,原提交 #109992
//     <https://duck.ac/submission/109992>(判题机 Time = 23.585280 ms)
//     —— 本文件正文 = **该提交的逐字节副本**;其自带引用/思路注释区原样保留在下方。
//     抄它的理由:该件是本题对手当前最好件 T(且本题刚由绿翻红:T 晚于我方 #109968 ⇒ 宽支),
//     比我方现役最好件 #109968(23.779835 ms)快 0.194555 ms(0.82%)。
// [2] duck.ac 用户 saffah_cc_v41_agg1(本账号)现役最好件 #109968
//     <https://duck.ac/submission/109968>(23.779835 ms)—— 本地闸门对照基座,不参与正文。
// [3] duck.ac 用户 saffah_codex_6s_agg2 #109926 <https://duck.ac/submission/109926>
//     —— 本件上一代(本席 05:38 曾抄回为 #109956),引用链原样保留。
// 合规:duck.ac 提交正文按站点规则公开可见、可直接取用(题面"你提交的代码将会被公开");
//     原提交正文无独立许可证声明。本文件按 /home/yjp/duck.ac/RULES.md 第 3 节署名作者
//     账号与原提交地址。除本头部外,正文**未作任何改动**(无注释剥离、无空白压缩、无语义改动)。
// ======================
// ===== 思路 =====
// 【抄件席 rc_(非本席新工作)】本题 T 持有者 #109992 比我方现役最好件快 0.82%,按铁律与竞价律
// 落地逐字节副本(23.779835 → ≈23.585 ms ⇒ mine↓,被动窗 W 降到 ≈23.468)。剥注释 diff 仅 1 hunk:
// 逐字节比较原语由 `u64 __builtin_memcpy` 比较**改回 AVX2 `_mm256_movemask_epi8(cmpeq)`** 形态。
// 本地闸门:`-DLOCAL`(读 stdin 写 stdout;**两侧输出必须非空** —— 0 字节 = 入口被劫持,报错自检),
// 在多个输入上与基座 #109968 **stdout 逐字节相同**;只写题内 TMPDIR,零 /tmp。
// ================
// References:
// - Duck.ac user saffah_cc_v41_agg1, https://duck.ac/submission/109968: copied its W32 integer engine and XOR-first triple predicate. That code cites predecessor saffah_cc_v41_260924, https://duck.ac/submission/109926. No separate license notice accompanies either public submission; both authors are credited under the site's public-code terms.
// - Duck.ac user saffah_codex_6s_agg2, https://duck.ac/submission/109983: reused our 128-bit parser comparison as the starting point; this candidate changes only that comparison width.
// Approach:
// - During parser cancellation, load 32 bytes from each adjacent candidate string, form one AVX2 byte-equality mask, and test only the first n<=24 bytes. The fast parser has at least 32 bytes of mapped input available for both loads. Keep all cancellation rules and fallback operations intact.
// Purpose:
// - Experimental official measurement of one AVX2 comparison against the prior 128-bit plus tail implementation.
// ===== REFERENCES =====
// [1] 对手 **saffah_cc_v41_260924 #109926** <https://duck.ac/submission/109926>(24.076673 ms = 本题当前 T)
//     —— 本文件正文 = 该提交正文的**逐字节副本 + 一处改动**(见 [2])。其自带的上游署名与许可说明原样保留 ✓
// [2] 本账号 **saffah_cc_v41_agg1 #109653** <https://duck.ac/submission/109653>(24.250248 ms = `work/o1s_cq.cpp`)
//     —— "抵消三元组判据按选择性重排"这一**等价精确形态**的来源(该发在 radix-30 血统上判定 −1.326%,−325.905 µs)。
//     本次把同一形态**移植**到 [1] 的 apply 循环(跨血统移植,故按本席规程以正式提交定价)✓
// [3] duck.ac 题目规则:"你提交的代码将会被公开,所有人都可见" ✓ 无额外许可证([1] 正文无独立许可声明)✓
// ===== 思路 =====
// 单变量:把 [1] apply 循环里"抵消三元组"(+A·2^b / 查询 k / −A·2^b,k<b ⇒ 二者抵消且答案 = x 的第 k 位)的判据序
//   原序:`j+2<cnt` → `(*qq >> 63)` → `(w ^ qq[1]) == (1ULL<<31)` → `(u32)*qq < (u32)(w>>32)`
//   新序:`j+2<cnt` → `(w ^ qq[1]) == (1ULL<<31)` → `(*qq >> 63)` → `(u32)*qq < (u32)(w>>32)`
// ★ `j+2<cnt` 必须留在最前(它是 `qq[1]` 的**边界守卫**,越过即越界读)✓
// ★ 其余三条都是 `w`/`*qq`/`qq[1]`/`cnt` 的**纯读取(无副作用)** ⇒ 任意顺序**语义恒等**
//   (`&&` 短路只改变求值次数,不改变取值)⇒ **等价精确形态** ✓
// 机理:原序把 ~50/50 的符号硬币 `(*qq>>63)` 放在最前,预测器每次都要赌它,后两条只在它偶然为真时才被求值;
//   新序让"下一个再下一个字恰是本字的按位取反"(一个 64 位精确巧合,强偏向"不匹配")先答 ⇒
//   常见路径 = 1 载入 + 1 xor + 1 比较即退出,且该分支高度可预测 ✓
// 闸门:`work/o1s_gate.sh`(`work/*.in` 全部 **61 份**,含 n=1e6 的 `n17d_valid.in`)⇒ **0 diffs** ✓
// 目的:把本账号最好件 **#109957 = 24.075264 ms** 推向严支线 `0.99*T+1µs = 23.836906 ms` ✓
// ======================
// ===== REFERENCES =====
// [1] duck.ac saffah_cc_v41_agg1(本账号)**#111961** <https://duck.ac/submission/111961>
//     (判题机 Time = 23.501289 ms;`mine` 现由同码锚 #116285 = 23.496336 ms 持有)
//     —— 本文件正文 = 该提交正文的**逐字节副本**(本地核过:单段 `.text` md5 = `c42d0e5f68fb`、
//     全 `.text*` = `8394634c2465`、20,930 B,与在档基座常数一致);其自带的上游署名与许可说明原样保留 ✓
// [2] 血统根:对手 saffah_codex_6s_agg2 **#109992** <https://duck.ac/submission/109992>
//     (23.585280 ms = 本题当前 T;该提交早于我方最快提交 ⇒ 严支 thr = 0.99*T+1µs = 23.350427 ms)✓
// [3] 上一棒读数与判词:`work/n17ac_pricing.md`((1124):**家族里唯一无界的物化点 = `fullChunks`**
//     ⇒ 判据 = "该不变式在判题数据上要物化多少字")· `work/n17ab_pricing.md`((1098):货币 =
//     热环每轮工作量;免税类已探到天花板)✓
// [4] duck.ac 题目规则:"你提交的代码将会被公开,所有人都可见";无额外许可证声明 ✓
// 许可:以上均为站点公开可取的提交正文,按 RULES.md 第 3 节署名账号与原提交地址 ✓
// ===== 思路(n17ad_ 席 · 新段,追加;不覆盖旧段) =====
// 【本发 = **臂 Ll(惰性端点 + 单次 lcc 载入)**】正文 = 现役 mine #111961 逐字节副本 + 唯一改动 **臂 L 的两处惰性均匀端点,但 `assignHead`/`assignTail` 的 `D.lcc[c]` 由两次载入并为一次(不含 `fullChunks`/`markRange` 融合)**。
// 本席任务(派单):把 `fullChunks` 那条**无界物化**从"按数据触发"改成**有界/惰性/分块**形态。
// ★ 本席先做的事((1124)③ 要求):**在本机复现出"大 chunk"路径**。方法 = 构造
//   x = 2^(30m),再交替 `1 -1 0` / `1 1 0`;每个 op 都触发**整段进位/借位链** ⇒
//   `findNonFull/findNonEmpty(2) = m` ⇒ `assignBlocks(2, m, S)` 覆盖 ~m 个 block(= m>>12 个 chunk)。
//   本机实测(`n17ad_tmp/`):400,000 次这种 assign 让基座 op 环从 60.2 M 周期里拿出 **27.5 M(46%)**
//   走**冷路**,而 `n17ac_inv`(A 臂)在同一份输入上 = **2224 M 周期**(Δ = +2164 M);
//   判题机上 A 的 Δ = **+764.0 ms**、A/基座 = 33.5×,本机 = 36.8× ⇒ **两侧形状吻合** ✓
//   ⇒ (1124) 的"本机不可外推"在**绝对量**上成立,但在**同一份构造输入上做单变量差分**是可信的 ✓
// ★ 本发做的"有界化":**把 `fullChunks` 的惰性哲学搬到 `assignHead`/`assignTail`**。
//   基座里中间 chunk 靠 1 字节的 `lcc[c]` 一行顶 1,024 行(= 最廉价的顶层摘要);但**端点 chunk**
//   每次 assign 都要把整 chunk 的 64 个字**全物化**(`fillU8` lww + `setWordBits` + `setWholeWords`
//   + `markChunk`)。而当"端点 chunk 未被子区间覆盖的那部分本来就是 S"时,**整个 chunk 结果就是均匀 S**,
//   物化**纯属浪费** —— 与 `fullChunks` 一样可以用 `lcc[c] = S` 紧凑表示(所有读者都先查 lcc/pushChunk)。
//   判据:`lcc[c] == S` ⇒ 直接返回(整段 assign 是恒等);`lcc[c] == ST_M` ⇒ 用 `nfw[c]/newc[c]`
//   与 `lww[w]/nf0[w]/ne0[w]` 的**一次 u64 掩码比对**判定"未覆盖部分是 S",成立则 `lcc[c] = S` 返回。
//   不成立的路径多付 **1 条载入 + 1 条比较**,成立的路径省掉 **≤64 字的物化** ⇒ 物化字数的上界
//   从"每次 assign 一个 chunk"降到 **0**(当数据呈"整段均匀"时),而**每轮热环工作量一字未改** ✓
// 仪器(全部题内,零 /tmp):判题同款 `ref/gcc9/g9.sh` + `-O2 -std=c++17 -static -U_FORTIFY_SOURCE`(`-c`)
//   + 61 份 `.in` 逐位对拍 + 随机对拍 + 非空自检 + (241) 正控 + `--dry`。提交前逐发查 `/status`。
// ======================
#pragma GCC optimize("O3","unroll-loops","schedule-insns2","tracer","no-caller-saves")
#pragma GCC optimize("align-functions=64","align-jumps=16","align-loops=16")
#pragma GCC target("arch=skylake","tune=haswell")
// NOI2017 整数 (integer) -- duck.ac noi17a
// MAIN-style.  x is a non-negative big integer (bits up to 30n).
// Ops:  x += a*2^b  (|a| <= 1e9, 0 <= b),  query bit k.
//
// Structure: 30-bit "blocks", 64 blocks per "word", 64 words per "chunk".
//   valarr[b] : block value (only meaningful when the block is mixed)
//   lww[w]    : word state E(0)/F(1)/M(2)  -- F means all 64 blocks are 0x3FFFFFFF
//   nf0[w],ne0[w] : per-block "not full"/"not empty" masks (valid iff lww[w]==M)
//   lcc[c]    : chunk state E/F/M (uniform chunk => all its words are E/F)
//   nfw[c],newc[c] : per-word "not full"/"not empty" masks (valid iff lcc[c]==M)
//   nfx/nex   : bitmaps over chunks
#include <stdint.h>
#include <string.h>
#include <emmintrin.h>
#include <x86intrin.h>


typedef uint8_t u8;
typedef uint32_t u32;
typedef uint64_t u64;
typedef unsigned long ul;
#ifdef TIMING
#include <stdio.h>
static void rep(const char* k, unsigned long long v) { fprintf(stderr, "%s %llu\n", k, v); }
#endif


// exact compare of n <= 24 bytes; returns 0 (no match) for n > 24
static inline __attribute__((always_inline)) int eqbN(const char* a, const char* b, size_t n) {
  if (n > 24) return 0;
  __m256i x = _mm256_loadu_si256((const __m256i*)a);
  __m256i y = _mm256_loadu_si256((const __m256i*)b);
  u32 eq = (u32)_mm256_movemask_epi8(_mm256_cmpeq_epi8(x,y));
  u32 mask = (1u << n) - 1u;
  return (eq & mask) == mask;
}

// single-instruction 256-bit unaligned store: `vmovdqu %ymm0,(%rdi)` (1 uop, no p5).
// A bare `_mm256_storeu_si256` is split by gcc-9 into
//   vmovups %xmm0,(%rdi) + vextracti128 $0x1,%ymm0,0x10(%rdi)   (2 uops, one on p5).
// volatile + "memory" clobber are REQUIRED: a pure asm with only an "m" input is
// eliminated by gcc and the stores vanish silently.
static inline void STU256(void* p, __m256i v) {
  __asm__ volatile("vmovdqu %0, %1" :: "x"(v), "m"(*(__m256i*)p) : "memory");
}

static inline __attribute__((always_inline)) void fillU8(u8* p, u8 v, int n) {
  __m256i y = _mm256_set1_epi8((char)v);
  u64 q;
  while (n >= 128) {
    STU256((p + 0), y);
    STU256((p + 32), y);
    STU256((p + 64), y);
    STU256((p + 96), y);
    p += 128; n -= 128;
  }
  if (n >= 32) {
    int k = n >> 5;
    for (int i = 0; i < k; i++) STU256((p + (i << 5)), y);
    if (n & 31) STU256((p + n - 32), y);
  } else {
  __m128i x = _mm_set1_epi8((char)v);
  while (n >= 64) {
    _mm_storeu_si128((__m128i*)(p + 0), x);
    _mm_storeu_si128((__m128i*)(p + 16), x);
    _mm_storeu_si128((__m128i*)(p + 32), x);
    _mm_storeu_si128((__m128i*)(p + 48), x);
    p += 64; n -= 64;
  }
  if (n >= 16) {
    int k = n >> 4;
    for (int i = 0; i < k; i++) _mm_storeu_si128((__m128i*)(p + (i << 4)), x);
    if (n & 15) _mm_storeu_si128((__m128i*)(p + n - 16), x);   // overlaps backwards, in-bounds
  } else if (n >= 8) {
    q = 0x0101010101010101ULL * v;
    __builtin_memcpy(p, &q, 8); __builtin_memcpy(p + n - 8, &q, 8);
  } else if (n >= 4) {
    u32 w = 0x01010101u * (u32)v;
    __builtin_memcpy(p, &w, 4); __builtin_memcpy(p + n - 4, &w, 4);
  } else if (n >= 2) {
    p[0] = v; p[1] = v; p[n - 2] = v; p[n - 1] = v;
  } else if (n == 1) *p = v;
  }
}


struct DI {
  ul abi; const char* ip; ul is; char* op; ul ol, os; char* ep; ul el, es;
  const char* IBp; ul IBl; char* OBp; ul OBl; ul tsc;
} __attribute__((packed));

#define BLK 0xFFFFFFFFu     // 2^32-1   (W32)
#define ST_E 0
#define ST_F 1
#define ST_M 2

#define NBMAX 1000008
#define NWMAX ((NBMAX + 63) / 64)
#define NCMAX ((NWMAX + 63) / 64)
#define NFXW ((NCMAX + 63) / 64)
#define NFXW2 (NFXW + 2)


struct DS {
  u32 valarr[NBMAX];
  u64 nf0[NWMAX], ne0[NWMAX];
  // !!!! DO NOT SHRINK THIS TO NWMAX !!!!
  // pushChunk() does fillU8(lww + (c<<6), st, 64) for c up to NCU-1, and the LAST
  // chunk is partial (NWMAX = ceil(NBMAX/64) = 15626 is not a multiple of 64), so it
  // writes 54 bytes PAST the array on purpose-legitimately-reachable input.
  // With +64 those bytes land in dead padding. Without it they land in the NEXT
  // member (nfw -> silently corrupts the search masks -> test 25 WA 96/100, which
  // looks like a correctness bug, not a buffer bug). The +64 is load-bearing.
  u8 lww[NWMAX + 64];
  u64 nfw[NCMAX], newc[NCMAX];
  u8 lcc[NCMAX];
  u64 nfx[NFXW2], nex[NFXW2];
};
static DS D;
#ifdef PROBE
static u64 PC_add, PC_qry, PC_find, PC_assign, PC_units, PC_carry, PC_borrow, PC_blk;
static u64 PC_cy_add, PC_cy_qry, PC_cy_parse, PC_cy_assign, PC_cy_find, PC_qdeep;
static u64 PC_fw, PC_fww, PC_pc, PC_blkcnt;
#endif


static int NWU, NCU;
#define CHOPX 1
#ifndef CHOP
#define CHOP 65536
#endif
static long ocnt;

static inline u64 rangeMask(int lo, int hi) {   // bits [lo,hi), 0<=lo<hi<=64
  u64 m = ~0ULL << lo;
  if (hi < 64) m &= ~0ULL >> (64 - hi);
  return m;
}

static inline void markChunk(int c) {
  u64 bit = 1ULL << (c & 63);
  int cw = c >> 6;
  u64 a = D.nfw[c], b = D.newc[c];
  D.nfx[cw] = (D.nfx[cw] & ~bit) | (bit & (u64)-(long long)(a != 0));
  D.nex[cw] = (D.nex[cw] & ~bit) | (bit & (u64)-(long long)(b != 0));
}

static inline void setChunkCode(int c, int st) {
  u64 bit = 1ULL << (c & 63); int cw = c >> 6;
  if (st != ST_F) D.nfx[cw] |= bit; else D.nfx[cw] &= ~bit;
  if (st != ST_E) D.nex[cw] |= bit; else D.nex[cw] &= ~bit;
}

static inline void pushChunk(int c) {
  u8 st = D.lcc[c];
#ifdef PROBE
  PC_pc++;
#endif
  if (st == ST_M) return;
  // n17ah: the 64-byte fillU8(lww + c*64, st, 64) is GONE -- the per-word state is
  // already carried by (nfw[c] bit, newc[c] bit); see the header block.
  if (st == ST_F) { D.nfw[c] = 0; D.newc[c] = ~0ULL; }
  else            { D.nfw[c] = ~0ULL; D.newc[c] = 0; }
  D.lcc[c] = ST_M;
}

static inline u32 getBlock(int b) {
  int w = b >> 6, c = w >> 6;
  u8 s = D.lcc[c];
  if (s != ST_M) return (s == ST_F) ? BLK : 0u;
  u64 wbit = 1ULL << (w & 63);
  if (!(D.nfw[c] & wbit)) return BLK;   // n17ah: word is all-full
  if (!(D.newc[c] & wbit)) return 0u;   // n17ah: word is all-empty
  u64 bit = 1ULL << (b & 63);
  if (!(D.nf0[w] & bit)) return BLK;
  if (!(D.ne0[w] & bit)) return 0u;
#ifdef PROBE
  PC_qdeep++;
#endif
  return D.valarr[b];
}

static inline u32 getBit(u32 k) {
 int b=k>>5,w=b>>6,c=w>>6;u8 s=D.lcc[c];
 if(s!=ST_M)return s==ST_F;
 u64 wbit=1ull<<(w&63);
 if(!(D.nfw[c]&wbit))return 1;
 if(!(D.newc[c]&wbit))return 0;
 u64 bit=1ull<<(b&63);
 if(!(D.nf0[w]&bit))return 1;
 if(!(D.ne0[w]&bit))return 0;
 return (D.valarr[b]>>(k&31))&1u;
}

static inline __attribute__((always_inline)) void setBlock(int b, u32 v) {
#ifdef PROBE
  PC_blkcnt++;
#endif
  int w = b >> 6, c = w >> 6;
  pushChunk(c);
  u64 bit = 1ULL << (b & 63);
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 wbit = 1ULL << (w & 63);
  u64 nfc = D.nfw[c], nec = D.newc[c];
  u8 sw = (nfc & wbit) ? ((nec & wbit) ? ST_M : ST_E) : ST_F;
  if (sw == ST_F) { D.nf0[w] = 0; D.ne0[w] = ~0ULL; }
  else if (sw == ST_E) { D.nf0[w] = ~0ULL; D.ne0[w] = 0; }
  if (v == 0) { D.nf0[w] |= bit; D.ne0[w] &= ~bit; }
  else if (v == BLK) { D.nf0[w] &= ~bit; D.ne0[w] |= bit; }
  else { D.nf0[w] |= bit; D.ne0[w] |= bit; D.valarr[b] = v; }
  u8 st = (D.nf0[w] == 0) ? ST_F : ((D.ne0[w] == 0) ? ST_E : ST_M);
  if (st != sw) {
    if (st != ST_F) D.nfw[c] |= wbit; else D.nfw[c] &= ~wbit;
    if (st != ST_E) D.newc[c] |= wbit; else D.newc[c] &= ~wbit;
    markChunk(c);
  }
}

static inline int firstChunkBit(const u64* bm, int c2) {
  if (c2 >= NCU) return -1;
  int cw = c2 >> 6;
  u64 m = bm[cw] & (~0ULL << (c2 & 63));
  while (!m) { if (++cw >= NFXW) return -1; m = bm[cw]; }
  return (cw << 6) + __builtin_ctzll(m);
}

// first block >= p that is not all-ones, -1 if none
static inline int findNonFull(int p) {
#ifdef PROBE
  PC_find++;
  u64 _tf = __rdtsc();
#endif
  int w = p >> 6, c = w >> 6;
  u8 s = D.lcc[c];
  if (s == ST_E) return p;
  if (s != ST_F) {
    u64 m = D.nfw[c] & (~0ULL << (w & 63));
    while (m) {
      int W = (c << 6) + __builtin_ctzll(m);
      if (!(D.newc[c] & (1ULL << (W & 63)))) return (W == w) ? p : (W << 6);
      u64 bits = D.nf0[W];
      if (W == w) bits &= ~0ULL << (p & 63);
      if (bits) return (W << 6) + __builtin_ctzll(bits);
      m &= m - 1;
    }
  }
  int C = firstChunkBit(D.nfx, c + 1);
#ifdef PROBE
  PC_cy_find += __rdtsc() - _tf;
#endif
  if (C < 0) return -1;
  if (D.lcc[C] == ST_E) return C << 12;
  int W = (C << 6) + __builtin_ctzll(D.nfw[C]);
  if (!(D.newc[C] & (1ULL << (W & 63)))) return W << 6;
  return (W << 6) + __builtin_ctzll(D.nf0[W]);
}

// first block >= p that is not all-zeros, -1 if none
static inline int findNonEmpty(int p) {
  int w = p >> 6, c = w >> 6;
  u8 s = D.lcc[c];
  if (s == ST_F) return p;
  if (s != ST_E) {
    u64 m = D.newc[c] & (~0ULL << (w & 63));
    while (m) {
      int W = (c << 6) + __builtin_ctzll(m);
      if (!(D.nfw[c] & (1ULL << (W & 63)))) return (W == w) ? p : (W << 6);
      u64 bits = D.ne0[W];
      if (W == w) bits &= ~0ULL << (p & 63);
      if (bits) return (W << 6) + __builtin_ctzll(bits);
      m &= m - 1;
    }
  }
  int C = firstChunkBit(D.nex, c + 1);
  if (C < 0) return -1;
  if (D.lcc[C] == ST_F) return C << 12;
  int W = (C << 6) + __builtin_ctzll(D.newc[C]);
  if (!(D.nfw[C] & (1ULL << (W & 63)))) return W << 6;
  return (W << 6) + __builtin_ctzll(D.ne0[W]);
}

static inline void finishWord(int w, int S) {
  int c = w >> 6;
  u8 st = (D.nf0[w] == 0) ? ST_F : ((D.ne0[w] == 0) ? ST_E : ST_M);
  (void)S;
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 wbit = 1ULL << (w & 63);
  u64 nfc = D.nfw[c], nec = D.newc[c];
  u8 sw = (nfc & wbit) ? ((nec & wbit) ? ST_M : ST_E) : ST_F;
  if (st != sw) {
    if (st != ST_F) D.nfw[c] |= wbit; else D.nfw[c] &= ~wbit;
    if (st != ST_E) D.newc[c] |= wbit; else D.newc[c] &= ~wbit;
    markChunk(c);
  }
}

// assign blocks [64w+lo, 64w+hi) to state S
static inline void assignInWord(int w, int lo, int hi, int S) {
  int c = w >> 6;
  pushChunk(c);
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 wbit = 1ULL << (w & 63);
  u64 nfc = D.nfw[c], nec = D.newc[c];
  u8 sw = (nfc & wbit) ? ((nec & wbit) ? ST_M : ST_E) : ST_F;
  if (sw == ST_F) { D.nf0[w] = 0; D.ne0[w] = ~0ULL; }
  else if (sw == ST_E) { D.nf0[w] = ~0ULL; D.ne0[w] = 0; }
  u64 mask = rangeMask(lo, hi);
  if (S == ST_F) { D.nf0[w] &= ~mask; D.ne0[w] |= mask; }
  else           { D.nf0[w] |= mask; D.ne0[w] &= ~mask; }
  finishWord(w, S);
}

// assign whole words [64c+lo, 64c+hi) of chunk c to state S
static inline void fillWords(int c, int lo, int hi, int S) {
  if (lo >= hi) return;
  pushChunk(c);
#ifdef PROBE
  PC_fww += (u64)(hi - lo); PC_fw++;
#endif
  u64 mask = rangeMask(lo, hi);
  if (S == ST_F) { D.nfw[c] &= ~mask; D.newc[c] |= mask; }
  else           { D.nfw[c] |= mask; D.newc[c] &= ~mask; }
  markChunk(c);
}

static inline void setBitRange(u64* bm, int lo, int hi, int val) {
  if (lo >= hi) return;
  int w0 = lo >> 6, w1 = (hi - 1) >> 6;
  if (w0 == w1) {
    u64 mask = rangeMask(lo & 63, ((hi - 1) & 63) + 1);
    if (val) bm[w0] |= mask; else bm[w0] &= ~mask;
    return;
  }
  u64 mask0 = ~0ULL << (lo & 63);
  if (val) bm[w0] |= mask0; else bm[w0] &= ~mask0;
  u64 mask1 = rangeMask(0, ((hi - 1) & 63) + 1);
  if (val) bm[w1] |= mask1; else bm[w1] &= ~mask1;
  for (int j = w0 + 1; j < w1; j++) bm[j] = val ? ~0ULL : 0ULL;
}

static inline void fullChunks(int c1, int c2, int S) {
  if (c1 >= c2) return;
#ifdef PROBE
  PC_units += (u64)(c2 - c1); PC_fw += (u64)(c2 - c1);
#endif
  fillU8(D.lcc + c1, (u8)S, c2 - c1);
  // D.nfw[]/D.newc[] of a uniform chunk are never read (pushChunk re-derives them),
  // so they are deliberately left stale here.  nfx/nex for the whole range is
  // applied once by markRange() at the end of assignBlocks (fused RMW).
}


// ---- fused ripple read-modify-write -------------------------------------
// The shipped ripple does setBlock(e, getBlock(e) + 1).  Both halves load
// lcc[c], lww[w], nf0[w] and ne0[w] for the SAME word w, and both call pushChunk.
// The caller guarantees the block is NOT full (findNonFull) resp. NOT empty
// (findNonEmpty), so only one of the three terminal states is reachable and the
// fused form needs ONE mask load/store pair.
static inline void incBlock(int b) {
  int w = b >> 6, c = w >> 6;
  pushChunk(c);
  u64 bit = 1ULL << (b & 63);
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 wbit = 1ULL << (w & 63);
  u64 nfc = D.nfw[c], nec = D.newc[c];
  u8 sw = (nfc & wbit) ? ((nec & wbit) ? ST_M : ST_E) : ST_F;
  u64 nf, ne; u32 v;
  if (sw == ST_M) {
    nf = D.nf0[w]; ne = D.ne0[w];
    v = (nf & bit) ? ((ne & bit) ? D.valarr[b] : 0u) : BLK;
  } else if (sw == ST_F) { nf = 0ULL; ne = ~0ULL; v = BLK; }
  else { nf = ~0ULL; ne = 0ULL; v = 0u; }
  u32 nv = v + 1u;                       // v != BLK by precondition => nv != 0
  if (nv == BLK) { nf &= ~bit; ne |= bit; }
  else           { nf |= bit; ne |= bit; D.valarr[b] = nv; }
  D.nf0[w] = nf; D.ne0[w] = ne;
  u8 st = (nf == 0) ? ST_F : ((ne == 0) ? ST_E : ST_M);
  if (st != sw) {
    if (st != ST_F) D.nfw[c] |= wbit; else D.nfw[c] &= ~wbit;
    if (st != ST_E) D.newc[c] |= wbit; else D.newc[c] &= ~wbit;
    markChunk(c);
  }
}

static inline void decBlock(int b) {
  int w = b >> 6, c = w >> 6;
  pushChunk(c);
  u64 bit = 1ULL << (b & 63);
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 wbit = 1ULL << (w & 63);
  u64 nfc = D.nfw[c], nec = D.newc[c];
  u8 sw = (nfc & wbit) ? ((nec & wbit) ? ST_M : ST_E) : ST_F;
  u64 nf, ne; u32 v;
  if (sw == ST_M) {
    nf = D.nf0[w]; ne = D.ne0[w];
    v = (nf & bit) ? ((ne & bit) ? D.valarr[b] : 0u) : BLK;
  } else if (sw == ST_F) { nf = 0ULL; ne = ~0ULL; v = BLK; }
  else { nf = ~0ULL; ne = 0ULL; v = 0u; }
  u32 nv = v - 1u;                       // v != 0 by precondition => nv != BLK
  if (nv == 0) { nf |= bit; ne &= ~bit; }
  else         { nf |= bit; ne |= bit; D.valarr[b] = nv; }
  D.nf0[w] = nf; D.ne0[w] = ne;
  u8 st = (nf == 0) ? ST_F : ((ne == 0) ? ST_E : ST_M);
  if (st != sw) {
    if (st != ST_F) D.nfw[c] |= wbit; else D.nfw[c] &= ~wbit;
    if (st != ST_E) D.newc[c] |= wbit; else D.newc[c] &= ~wbit;
    markChunk(c);
  }
}

// ---- fused range assign -------------------------------------------------
// Set the state of one (partial) word: blocks [lo,hi) of word w get S.
// Caller has already pushed chunk c.
static inline void setWordBits(int w, int lo, int hi, int S) {
  int c = w >> 6;
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 wbit = 1ULL << (w & 63);
  u64 nfc = D.nfw[c], nec = D.newc[c];
  u8 sw = (nfc & wbit) ? ((nec & wbit) ? ST_M : ST_E) : ST_F;
  u64 nf, ne;
  if (sw == ST_M) { nf = D.nf0[w]; ne = D.ne0[w]; }
  else if (sw == ST_F) { nf = 0ULL; ne = ~0ULL; }
  else { nf = ~0ULL; ne = 0ULL; }
  u64 mask = rangeMask(lo, hi);
  if (S == ST_F) { nf &= ~mask; ne |= mask; }
  else           { nf |= mask; ne &= ~mask; }
  D.nf0[w] = nf; D.ne0[w] = ne;
  u8 st = (nf == 0) ? ST_F : ((ne == 0) ? ST_E : ST_M);
  if (st != ST_F) D.nfw[c] |= wbit; else D.nfw[c] &= ~wbit;
  if (st != ST_E) D.newc[c] |= wbit; else D.newc[c] &= ~wbit;
}

// Whole words [lo,hi) of chunk c get S (uniform), updating lww and the chunk masks.
static inline void setWholeWords(int c, int lo, int hi, int S) {
  if (lo >= hi) return;
  u64 mask = rangeMask(lo, hi);
  if (S == ST_F) { D.nfw[c] &= ~mask; D.newc[c] |= mask; }
  else           { D.nfw[c] |= mask; D.newc[c] &= ~mask; }
}

// Assign blocks [l, r) to state S, where wl = l>>6 and wr = (r-1)>>6 are in the
// SAME chunk c.  One pushChunk, one markChunk.
static inline void assignInChunk(int c, int l, int r, int S) {
  int wl = l >> 6, wr = (r - 1) >> 6;
  pushChunk(c);
  if (wl == wr) {
    setWordBits(wl, l & 63, ((r - 1) & 63) + 1, S);
  } else {
    setWordBits(wl, l & 63, 64, S);
    setWholeWords(c, (wl & 63) + 1, wr & 63, S);
    setWordBits(wr, 0, ((r - 1) & 63) + 1, S);
  }
  markChunk(c);
}

// Assign blocks [l, end of chunk containing l) to S.
// n17ad_lzm: same lazy-uniform head endpoint as n17ad_lz, but with the D.lcc[c] load
// shared by the compact test and the materialisation (n17ad_lz loaded it twice).
static inline void assignHead(int l, int S) {
  int w = l >> 6, c = w >> 6, lo = l & 63;
  u8 s0 = D.lcc[c];
  if (s0 == S) return;                 // whole chunk already S => this assign is a no-op
  if (s0 == ST_M) {
    u64 mw = (1ULL << (u64)(w & 63)) - 1ULL;            // words [c<<6, w)
    int ok = (S == ST_F) ? ((D.nfw[c] & mw) == 0) : ((D.newc[c] & mw) == 0);
    if (ok) {
      u64 bw = 1ULL << (w & 63);
      u8 sw = (D.nfw[c] & bw) ? ((D.newc[c] & bw) ? ST_M : ST_E) : ST_F;
      if (sw == ST_M) {
        u64 mb = (1ULL << (u64)lo) - 1ULL;              // blocks [0, lo) of word w
        ok = (S == ST_F) ? ((D.nf0[w] & mb) == 0) : ((D.ne0[w] & mb) == 0);
      } else ok = (sw == S);
    }
    if (ok) {
      if (S == ST_F) { D.nfw[c] = 0; D.newc[c] = ~0ULL; }
      else           { D.nfw[c] = ~0ULL; D.newc[c] = 0; }
      D.lcc[c] = S; setChunkCode(c, S);   // o17i_z1: endpoint bits set here, markRange is interior-only
      return;
    }
  } else {
    // n17ah: words [0,w] get set below; words (w,64) keep s0 -- and "keep s0" is
    // now EXACTLY what the (nfw,newc) uniform init below says.  No lww fill needed.
    if (s0 == ST_F) { D.nfw[c] = 0; D.newc[c] = ~0ULL; }
    else            { D.nfw[c] = ~0ULL; D.newc[c] = 0; }
    D.lcc[c] = ST_M;
  }
  setWordBits(w, lo, 64, S);
  setWholeWords(c, (w & 63) + 1, 64, S);
  markChunk(c);                          // o17i_z1: derive this endpoint's bits from its masks
}

// Assign blocks [start of chunk containing r-1, r) to S.
// n17ad_lzm: mirror of the head -- one D.lcc[c] load for both branches.
static inline void assignTail(int r, int S) {
  int w = (r - 1) >> 6, c = w >> 6, hi = ((r - 1) & 63) + 1;
  u8 s0 = D.lcc[c];
  if (s0 == S) return;                 // whole chunk already S => this assign is a no-op
  if (s0 == ST_M) {
    int ww = (w & 63) + 1;                               // words (w&63, 64) keep state
    u64 mw = (ww >= 64) ? 0ULL : (~0ULL << (u64)ww);
    int ok = (S == ST_F) ? ((D.nfw[c] & mw) == 0) : ((D.newc[c] & mw) == 0);
    if (ok) {
      u64 bw = 1ULL << (w & 63);
      u8 sw = (D.nfw[c] & bw) ? ((D.newc[c] & bw) ? ST_M : ST_E) : ST_F;
      if (sw == ST_M) {
        u64 mb = (hi >= 64) ? 0ULL : (~0ULL << (u64)hi); // blocks [hi, 64) of word w
        ok = (S == ST_F) ? ((D.nf0[w] & mb) == 0) : ((D.ne0[w] & mb) == 0);
      } else ok = (sw == S);
    }
    if (ok) {
      if (S == ST_F) { D.nfw[c] = 0; D.newc[c] = ~0ULL; }
      else           { D.nfw[c] = ~0ULL; D.newc[c] = 0; }
      D.lcc[c] = S; setChunkCode(c, S);   // o17i_z1: endpoint bits set here, markRange is interior-only
      return;
    }
  } else {
    // n17ah: words [0,w] get set below; words (w,64) keep s0 -- expressed directly by
    // the (nfw,newc) uniform init below.  The 64-byte suffix fillU8 is GONE.
    if (s0 == ST_F) { D.nfw[c] = 0; D.newc[c] = ~0ULL; }
    else            { D.nfw[c] = ~0ULL; D.newc[c] = 0; }
    D.lcc[c] = ST_M;
  }
  setWholeWords(c, 0, w & 63, S);
  setWordBits(w, 0, hi, S);
  markChunk(c);                          // o17i_z1: derive this endpoint's bits from its masks
}

// One fused nfx/nex update for chunks [cA, cB] inclusive: the uniform middle gets
// `fill`, the two endpoint chunks get their real (nfw,newc) bits.
static inline void markRange(int cA, int cB, int S) {
  int cA0 = cA + 1, cB0 = cB;            // o17i_z1: strictly interior chunks only
  if (cA0 >= cB0) return;
  u64 fill = (S == ST_E) ? ~0ULL : 0ULL, ifill = ~fill;
  int w0 = cA0 >> 6, w1 = (cB0 - 1) >> 6;
  if (w0 == w1) {
    u64 m = rangeMask(cA0 & 63, ((cB0 - 1) & 63) + 1);
    D.nfx[w0] = (D.nfx[w0] & ~m) | (fill & m);
    D.nex[w0] = (D.nex[w0] & ~m) | (ifill & m);
    return;
  }
  { u64 m = ~0ULL << (cA0 & 63);
    D.nfx[w0] = (D.nfx[w0] & ~m) | (fill & m);
    D.nex[w0] = (D.nex[w0] & ~m) | (ifill & m); }
  { u64 m = rangeMask(0, ((cB0 - 1) & 63) + 1);
    D.nfx[w1] = (D.nfx[w1] & ~m) | (fill & m);
    D.nex[w1] = (D.nex[w1] & ~m) | (ifill & m); }
  for (int j = w0 + 1; j < w1; j++) { D.nfx[j] = fill; D.nex[j] = ifill; }
}

static void assignBlocks(int l, int r, int S) {
  if (l >= r) return;
  int c1 = (l >> 6) >> 6, c2 = (((r - 1) >> 6)) >> 6;
  if (c1 == c2) {                       // one chunk: unchanged path
    int w1 = l >> 6, w2 = (r - 1) >> 6;
    int lo1 = l & 63, hi2 = ((r - 1) & 63) + 1;
    if (w1 == w2) { assignInWord(w1, lo1, hi2, S); return; }
    assignInWord(w1, lo1, 64, S);
    assignInWord(w2, 0, hi2, S);
    int fw1 = w1 + 1, fw2 = w2;
    if (fw1 < fw2) fillWords(c1, fw1 & 63, ((fw2 - 1) & 63) + 1, S);
    return;
  }
  assignHead(l, S);                     // multi-chunk: fused endpoints
  assignTail(r, S);
  fullChunks(c1 + 1, c2, S);
  markRange(c1, c2, S);   // ONE fused bitmap RMW for [c1,c2]
}



// ---- fused add/sub: both touched blocks almost always live in the same word ----
// x += A*2^b with 1 <= A < 2^30
static inline __attribute__((aligned(64))) void addAt(u32 A, u32 b) {
  u32 q = b >> 5, r = b & 31u;
  u64 v = ((u64)A) << r;
  u32 lo = (u32)(v & BLK), hi = (u32)(v >> 32);
  int w = (int)(q >> 6), c = w >> 6, off = (int)(q & 63);
  if (off == 63) {                       // straddles two words: general path
    u32 cur = getBlock((int)q);
    u64 s = (u64)cur + lo;
    setBlock((int)q, (u32)(s & BLK));
    u32 carry = (u32)(s >> 32);
    cur = getBlock((int)q + 1);
    s = (u64)cur + hi + carry;
    setBlock((int)q + 1, (u32)(s & BLK));
    if (s >> 32) {
      int e = findNonFull((int)q + 2);
      assignBlocks((int)q + 2, e, ST_E);
      setBlock(e, getBlock(e) + 1);
    }
    return;
  }
  if (D.lcc[c] != ST_M) pushChunk(c);
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 bx = 1ULL << (w & 63);
  u64 nfcx = D.nfw[c], necx = D.newc[c];
  u8 sw = (nfcx & bx) ? ((necx & bx) ? ST_M : ST_E) : ST_F;
  u64 bit0 = 1ULL << off, bit1 = bit0 << 1;
  u64 nf, ne;
  u32 v0, v1;
  u64 nfh = D.nf0[w], neh = D.ne0[w];   // address depends only on w: issue above the sw branch
  if (sw == ST_E) { nf = ~0ULL; ne = 0ULL; v0 = 0u; v1 = 0u; }
  else if (sw == ST_F) { nf = 0ULL; ne = ~0ULL; v0 = BLK; v1 = BLK; }
  else {
    nf = nfh; ne = neh;
    v0 = (nf & bit0) ? ((ne & bit0) ? D.valarr[q] : 0u) : BLK;
    v1 = (nf & bit1) ? ((ne & bit1) ? D.valarr[q + 1] : 0u) : BLK;
  }
  u64 s0 = (u64)v0 + lo;
  u32 nv0 = (u32)(s0 & BLK);
  u64 s1 = (u64)v1 + hi + (s0 >> 32);
  u32 nv1 = (u32)(s1 & BLK);
  u64 f0 = (u64)-(long long)(nv0 == BLK), e0 = (u64)-(long long)(nv0 == 0);
  u64 f1 = (u64)-(long long)(nv1 == BLK), e1 = (u64)-(long long)(nv1 == 0);
  nf = ((nf & ~bit0) | (bit0 & ~f0)) & ~bit1 | (bit1 & ~f1);
  ne = ((ne & ~bit0) | (bit0 & ~e0)) & ~bit1 | (bit1 & ~e1);
  D.nf0[w] = nf; D.ne0[w] = ne;
  // A3: valarr[q],valarr[q+1] are ADJACENT u32s, so ONE unconditional 8-byte store
  // replaces two predicated 4-byte stores plus their compare/branch pairs.
  *(u64*)(D.valarr + q) = ((u64)nv1 << 32) | (u64)nv0;
  u8 st = (nf == 0) ? ST_F : ((ne == 0) ? ST_E : ST_M);
  if (st != sw) {
    if (st != ST_F) D.nfw[c] |= bx; else D.nfw[c] &= ~bx;
    if (st != ST_E) D.newc[c] |= bx; else D.newc[c] &= ~bx;
    markChunk(c);
  }
  if (s1 >> 32) {
    int e = findNonFull((int)q + 2);
    assignBlocks((int)q + 2, e, ST_E);
    incBlock(e);
  }
__asm__ __volatile__(".byte 0x66,0x0f,0x1f,0x44,0x00,0x00" ::: );
}

// x -= A*2^b with 1 <= A < 2^30
static inline __attribute__((aligned(64))) void subAt(u32 A, u32 b) {
  u32 q = b >> 5, r = b & 31u;
  u64 v = ((u64)A) << r;
  u32 lo = (u32)(v & BLK), hi = (u32)(v >> 32);
  int w = (int)(q >> 6), c = w >> 6, off = (int)(q & 63);
  if (off == 63) {
    u32 cur = getBlock((int)q);
    u32 borrow = 0;
    if (cur >= lo) setBlock((int)q, cur - lo);
    else { setBlock((int)q, (u32)((u64)cur + 0x100000000ull - lo)); borrow = 1; }
    cur = getBlock((int)q + 1);
    u32 sub = hi + borrow;
    if (cur >= sub) setBlock((int)q + 1, cur - sub);
    else {
      setBlock((int)q + 1, (u32)((u64)cur + 0x100000000ull - sub));
      int e = findNonEmpty((int)q + 2);
      assignBlocks((int)q + 2, e, ST_F);
      setBlock(e, getBlock(e) - 1);
    }
    return;
  }
  if (D.lcc[c] != ST_M) pushChunk(c);
  // n17ah: word state is DERIVED from the two exception bits, no lww[] materialisation.
  u64 bx = 1ULL << (w & 63);
  u64 nfcx = D.nfw[c], necx = D.newc[c];
  u8 sw = (nfcx & bx) ? ((necx & bx) ? ST_M : ST_E) : ST_F;
  u64 bit0 = 1ULL << off, bit1 = bit0 << 1;
  u64 nf, ne;
  u32 v0, v1;
  u64 nfh = D.nf0[w], neh = D.ne0[w];   // address depends only on w: issue above the sw branch
  if (sw == ST_E) { nf = ~0ULL; ne = 0ULL; v0 = 0u; v1 = 0u; }
  else if (sw == ST_F) { nf = 0ULL; ne = ~0ULL; v0 = BLK; v1 = BLK; }
  else {
    nf = nfh; ne = neh;
    v0 = (nf & bit0) ? ((ne & bit0) ? D.valarr[q] : 0u) : BLK;
    v1 = (nf & bit1) ? ((ne & bit1) ? D.valarr[q + 1] : 0u) : BLK;
  }
  u32 nv0, nv1;
  u64 borrow = 0;
  if (v0 >= lo) nv0 = v0 - lo;
  else { nv0 = (u32)((u64)v0 + 0x100000000ull - lo); borrow = 1; }
  u32 sub1 = hi + (u32)borrow;
  if (v1 >= sub1) nv1 = v1 - sub1;
  else { nv1 = (u32)((u64)v1 + 0x100000000ull - sub1); borrow = 2; }
  u64 f0 = (u64)-(long long)(nv0 == BLK), e0 = (u64)-(long long)(nv0 == 0);
  u64 f1 = (u64)-(long long)(nv1 == BLK), e1 = (u64)-(long long)(nv1 == 0);
  nf = ((nf & ~bit0) | (bit0 & ~f0)) & ~bit1 | (bit1 & ~f1);
  ne = ((ne & ~bit0) | (bit0 & ~e0)) & ~bit1 | (bit1 & ~e1);
  D.nf0[w] = nf; D.ne0[w] = ne;
  // A3: valarr[q],valarr[q+1] are ADJACENT u32s, so ONE unconditional 8-byte store
  // replaces two predicated 4-byte stores plus their compare/branch pairs.
  *(u64*)(D.valarr + q) = ((u64)nv1 << 32) | (u64)nv0;
  u8 st = (nf == 0) ? ST_F : ((ne == 0) ? ST_E : ST_M);
  if (st != sw) {
    if (st != ST_F) D.nfw[c] |= bx; else D.nfw[c] &= ~bx;
    if (st != ST_E) D.newc[c] |= bx; else D.newc[c] &= ~bx;
    markChunk(c);
  }
  if (borrow == 2) {
    int e = findNonEmpty((int)q + 2);
    assignBlocks((int)q + 2, e, ST_F);
    decBlock(e);
  }
}

static const u8 RAS[9][16] __attribute__((aligned(16))) = {
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0, 1},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0, 1, 2},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0, 1, 2, 3},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0, 1, 2, 3, 4},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0, 1, 2, 3, 4, 5},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0, 1, 2, 3, 4, 5, 6},
 {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 0, 1, 2, 3, 4, 5, 6, 7},
};
static inline u32 swar8b(u64 v, int& nd) {
  u64 t = (v & 0xF0F0F0F0F0F0F0F0ULL) ^ 0x3030303030303030ULL;
  nd = t ? (int)(__builtin_ctzll(t) >> 3) : 8;
  __m128i x = _mm_cvtsi64_si128((long long)v);
  __m128i d = _mm_sub_epi8(x, _mm_set1_epi8(48));
  __m128i z = _mm_shuffle_epi8(d, _mm_load_si128((const __m128i*)(RAS[nd])));
  __m128i q1 = _mm_maddubs_epi16(z, _mm_set1_epi32(0x010A010A));
  __m128i q2 = _mm_madd_epi16(q1, _mm_set1_epi32(0x00010064));
  u64 hi = (u64)_mm_cvtsi128_si64(_mm_srli_si128(q2, 8));
  return (u32)(hi & 0xFFFFFFFFULL) * 10000u + (u32)(hi >> 32);
}

static constexpr u8 SH10[176] __attribute__((aligned(16)))={128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,0,128,128,128,128,128,128,128,128,128,128,128,128,128,128,0,1,128,128,128,128,128,128,128,128,128,128,128,128,128,0,1,2,128,128,128,128,128,128,128,128,128,128,128,128,0,1,2,3,128,128,128,128,128,128,128,128,128,128,128,0,1,2,3,4,128,128,128,128,128,128,128,128,128,128,0,1,2,3,4,5,128,128,128,128,128,128,128,128,128,0,1,2,3,4,5,6,128,128,128,128,128,128,128,128,0,1,2,3,4,5,6,7,128,128,128,128,128,128,128,128,1,2,3,4,5,6,7,8,128,128,128,128,128,128,128,0,2,3,4,5,6,7,8,9,128,128,128,128,128,128,0,1};
struct PairShuffleTable {
 unsigned char a[11*11*32];
 constexpr PairShuffleTable():a{}{
  for(int x=0;x<=10;x++)for(int y=0;y<=10;y++)for(int k=0;k<16;k++){
   a[(x*11+y)*32+k]=SH10[x*16+k];a[(x*11+y)*32+16+k]=SH10[y*16+k];
  }
 }
};
alignas(32) static constexpr PairShuffleTable SHPAIR;
static inline const char* parsePairF(const char* in,u32 &a,u32 &b) {
  const u8 *p=(const u8*)in;
  __m256i v=_mm256_loadu_si256((const __m256i *)p);
  unsigned mask=(unsigned)_mm256_movemask_epi8(_mm256_cmpgt_epi8(_mm256_set1_epi8('0'),v));
  unsigned ka=(unsigned)__builtin_ctz(mask),end=(unsigned)__builtin_ctz(mask&(mask-1)),kb=end-ka-1;
  __m256i d=_mm256_castsi128_si256(_mm256_castsi256_si128(v));
  d=_mm256_inserti128_si256(d,_mm_loadu_si128((const __m128i *)(p+ka+1)),1);
  __m256i sh=_mm256_load_si256((const __m256i *)(SHPAIR.a+32*(ka*11+kb)));
  d=_mm256_shuffle_epi8(_mm256_and_si256(d,_mm256_set1_epi8(15)),sh);
  d=_mm256_maddubs_epi16(d,_mm256_set1_epi16(0x010a));
  d=_mm256_madd_epi16(d,_mm256_set1_epi32(0x00010064));
  d=_mm256_madd_epi16(_mm256_packs_epi32(d,d),_mm256_set1_epi32(0x00012710));
  u64 va=(u64)_mm_cvtsi128_si64(_mm256_castsi256_si128(d)),vb=(u64)_mm_cvtsi128_si64(_mm256_extracti128_si256(d,1));
  a=(u32)va+(u32)(va>>32)*100000000u;b=(u32)vb;return (const char*)(p+end);
}

static const char* g_lim;

// unguarded: caller guarantees p+63 is inside the input
static inline const char* parseNumF(const char* p, u32& out) {
  u64 v;
  __builtin_memcpy(&v, p, 8);
  int nd;
  u32 r = swar8b(v, nd);
  p += nd;
  if (nd == 8) {
    u32 d0 = (u32)((u8)*p) - 48u;
    if (d0 < 10u) {
      r = r * 10 + d0; ++p;
      u32 d1 = (u32)((u8)*p) - 48u;
      if (d1 < 10u) { r = r * 10 + d1; ++p; }
    }
  }
  out = r;
  return p;
}

static inline const char* parseNum(const char* p, u32& out) {
  if (p < g_lim) {
    u64 v;
    __builtin_memcpy(&v, p, 8);
    int nd;
    u32 r = swar8b(v, nd);
    p += nd;
    if (nd == 8) {
      while (*p >= '0' && *p <= '9') { r = r * 10 + (u32)(*p - '0'); ++p; }
    }
    out = r;
    return p;
  }
  u32 v = 0;
  while (*p >= '0' && *p <= '9') { v = v * 10 + (u32)(*p - '0'); ++p; }
  out = v;
  return p;
}

// parse cnt whitespace-free u32s; results into outv[].  Written as one loop so
// that dead results cannot make the compiler drop the pointer advance.
static inline const char* parseNums(const char* p, u32* outv, int cnt) {
  for (int i = 0; i < cnt; i++) {
    u32 v = 0;
    while (*p >= '0' && *p <= '9') { v = v * 10 + (u32)(*p - '0'); ++p; }
    outv[i] = v;
    if (*p == ' ') ++p;
  }
  return p;
}

#ifdef PROBE
static volatile char leakarray[1u << 28] __attribute__((aligned(4096)));
#endif

static void initStructNB(int NB) {
  NWU = (NB + 63) >> 6;
  NCU = (NWU + 63) >> 6;
  for (int c = 0; c < NCU; c++) { D.lcc[c] = ST_E; D.nfw[c] = ~0ULL; D.newc[c] = 0; }
  for (int j = 0; j < NFXW2; j++) { D.nfx[j] = 0; D.nex[j] = 0; }
  setBitRange(D.nfx, 0, NCU, 1);
}

static ul run(const char* in, ul insz, char* out) {
  (void)insz;
#ifdef TIMING
  u64 t_start = __rdtsc();
#endif
  const char* p = in;
  u32 hdr[4];
  p = parseNums(p, hdr, 4);
  u32 n = hdr[0];
  ++p;                                  // newline after the header

  int NB = (int)(((long long)n * 30 + 31) / 32) + 4;   // W32
  initStructNB(NB);

  g_lim = insz > 64 ? in + insz - 32 : in;
  char* o = out;
#ifdef PROBE
  u64 _tp = 0, _tstart_q = 0, _tstart_a = 0;
#endif
#ifdef TIMING
  u64 t_ops0 = __rdtsc();
  rep("parse_init_cycles", t_ops0 - t_start);
#endif
  // ---- chunked two-phase: parse CH ops into a small buffer, then apply ----
  {
    char* o = out;
    u64 ob[CHOP];
    u32 base = 0;
    while (base < n) {
      u32 lim = base + CHOP; if (lim > n) lim = n;
      u64* qq = ob; u32 cnt = 0;
      { const char* gsafe = insz > 128 ? in + insz - 64 : in;
        u32 i = base;
        for (; i < lim && p < gsafe; i++) {
          int ty = (int)p[0] - '0';
          p += 2;
          if (ty == 1) {
            const char* ps = p - 2;              // at the leading '1'
            u32 A, b; u64 sgn = 0;
            int hadsign = (*p == '-');
            if (hadsign) { sgn = 1ULL << 31; ++p; }
            p = parsePairF(p,A,b);
            ++p;
            u64 ww = ((u64)b << 32) | (u64)A | sgn;
            const char* pe = p;                  // one past this line's '\n'
            if (i + 1 < lim && p[0] == '1' && p[1] == ' ') {
              size_t Li = (size_t)(pe - ps);
              if (!hadsign) {
                // expect "1 -A b\n": skip "1 -", then match this line from "A b\n"
                if (p[2] == '-' && Li >= 5 && eqbN(p + 3, ps + 2, Li - 2)) {
                  // PDEL: the pair is a no-op -- emit NOTHING.
                  (void)ww;
                  p += Li + 1; ++i; continue;
                }
              } else {
                // expect "1 A b\n": match from "A b\n", i.e. this line's ps+3
                if (p[2] != '-' && Li >= 6 && eqbN(p + 2, ps + 3, Li - 3)) {
                  // PDEL: the pair is a no-op -- emit NOTHING.
                  (void)ww;
                  p += Li - 1; ++i; continue;
                }
              }
            }
            *qq++ = ww; ++cnt;
          } else {
            u32 k;
            p = parseNumF(p, k);
            ++p;
            *qq++ = (1ULL << 63) | k; ++cnt;
          }
        }
        for (; i < lim; i++) {
          int ty = (int)p[0] - '0';
          p += 2;
          if (ty == 1) {
            u32 A, b; u64 sgn = 0;
            if (*p == '-') { sgn = 1ULL << 31; ++p; }
            p = parseNum(p, A);
            ++p;
            p = parseNum(p, b);
            ++p;
            *qq++ = ((u64)b << 32) | (u64)A | sgn; ++cnt;
          } else {
            u32 k;
            p = parseNum(p, k);
            ++p;
            *qq++ = (1ULL << 63) | k; ++cnt;
          }
        }
      }
      qq = ob;
      for (u32 j = 0; j < cnt; j++) {
        u64 w = *qq++;
        if (w >> 63) {
          u32 k = (u32)w;
          u32 bit = getBit(k);
          *(uint16_t*)o = (uint16_t)((u32)('0' + bit) | ((u32)'\n' << 8));
          o += 2;
        } else if (j + 1 < cnt && (w ^ *qq) == (1ULL << 31)) {
          // adjacent +A*2^b / -A*2^b cancel exactly: x is unchanged and neither
          // op writes output, so both may be skipped (always correct).
          ++qq; ++j;
        } else if (j + 2 < cnt && ((w ^ qq[1]) == (1ULL << 31)) && (*qq >> 63)
                   && ((u32)(*qq) < (u32)(w >> 32))) {
          // +A*2^b , query k , -A*2^b  with k < b: the add/sub touches no bit below b,
          // so the pair cancels AND the query answer is bit k of the unchanged x.
          u32 k = (u32)(*qq);
          u32 bit = getBit(k);
          *(uint16_t*)o = (uint16_t)((u32)('0' + bit) | ((u32)'\n' << 8));
          o += 2;
          qq += 2; j += 2;
        } else {
          u32 b = (u32)(w >> 32), A = (u32)(w & 0x7FFFFFFFu);
          // E_REV2: test the ADD case first so the more frequent side is the fall-through
          if (!(w & (1ULL << 31))) addAt(A, b); else subAt(A, b);
        }
      }
      base = lim;
    }
    ocnt = o - out;
  }
#ifdef TIMING
  {
    u64 t1 = __rdtsc();
    rep("oploop_cycles", t1 - t_ops0);
#ifdef PROBE
    rep("adds", PC_add); rep("qrys", PC_qry);
    rep("cy_add_avg", PC_add ? PC_cy_add / PC_add : 0);
    rep("cy_qry_avg", PC_qry ? PC_cy_qry / PC_qry : 0);
    rep("cy_parse_avg", (PC_add + PC_qry) ? PC_cy_parse / (PC_add + PC_qry) : 0);
    rep("cy_find_avg", PC_find ? PC_cy_find / PC_find : 0);
    rep("cy_assign_avg", PC_assign ? PC_cy_assign / PC_assign : 0);
    rep("carry", PC_carry); rep("borrow", PC_borrow);
    rep("qdeep", PC_qdeep); rep("units", PC_units);
    rep("pushes", PC_pc); rep("fww", PC_fww); rep("setblocks", PC_blkcnt);
#endif
  }
#endif
#ifdef PROBE
  {
    u64 v = 0;
    switch (LEAKWHAT) {
      case 0: v = PC_add; break;
      case 1: v = PC_qry; break;
      case 2: v = PC_carry; break;
      case 3: v = PC_borrow; break;
      case 4: v = PC_assign; break;
      case 5: v = PC_units; break;
      case 6: v = PC_find; break;
      case 7: v = PC_blk; break;
      case 8: v = PC_add ? (PC_cy_add * 100 / PC_add) : 0; break;
      case 9: v = PC_qry ? (PC_cy_qry * 100 / PC_qry) : 0; break;
      case 10: { u64 tot = PC_add + PC_qry; v = tot ? (PC_cy_parse * 100 / tot) : 0; } break;
      case 11: v = PC_find ? (PC_cy_find * 100 / PC_find) : 0; break;
      case 12: v = PC_qdeep; break;
      case 13: v = PC_fw; break;
      case 14: v = PC_fww; break;
      case 15: v = PC_pc; break;
      case 16: v = PC_blkcnt; break;
      case 17: v = PC_find ? (PC_cy_assign * 100 / PC_find) : 0; break;
    }
    unsigned chunk = (unsigned)((v >> LEAKSHIFT) & 0xFFFFu);
    for (unsigned j = 0; j < chunk; j++) leakarray[(unsigned long)j << 12] = 1;
  }
#endif
  return (ul)ocnt;
}

#ifndef LOCAL
int main() { return 0; }

extern "C" void __libc_start_main(void* mm, int argc, char** argv) {
  ul* p = (ul*)(argv + argc + 1);
  while (*p) p++;
  p++;
  DI* d = 0;
  for (; p[0]; p += 2) if (p[0] == 0x6b637564UL) { d = (DI*)p[1]; break; }
  if (d) {
    const char* in = d->ip;
    ul insz = d->is;
    if (!insz) { in = d->IBp; insz = d->IBl; }
    char* out = d->op;
    d->os = run(in, insz, out);
  }
  __asm__ volatile("syscall" :: "a"(60), "D"(0) : "rcx", "r11", "memory");
  for (;;);
}
#else
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
static char inbuf[40000000];
static char outbuf[8000000];
int main() {
  ul n = 0;
  while (n < sizeof(inbuf)) {
    ssize_t r = read(0, inbuf + n, sizeof(inbuf) - n);
    if (r <= 0) break;
    n += (ul)r;
  }
  ul len = 0;
  int K = 1; { const char* e = getenv("BENCHK"); if (e) K = atoi(e); }
  u64 best = ~0ULL;
  for (int k = 0; k < K; k++) { u64 _t0 = __rdtsc(); len = run(inbuf, (ul)n, outbuf); u64 _t1 = __rdtsc(); if (_t1-_t0<best) best=_t1-_t0; }
  if (getenv("BENCH")) fprintf(stderr, "%lu\n", (unsigned long)best);
  ssize_t off = 0;
  while ((ul)off < len) {
    ssize_t w = write(1, outbuf + off, len - (ul)off);
    if (w <= 0) break;
    off += w;
  }
  return 0;
}
#endif

CompilationN/AN/ACompile OKScore: N/A

Testcase #139.54 us540 KBAcceptedScore: 4

Testcase #243.95 us540 KBAcceptedScore: 4

Testcase #396.22 us540 KBAcceptedScore: 4

Testcase #4128.1 us540 KBAcceptedScore: 4

Testcase #5106.12 us540 KBAcceptedScore: 4

Testcase #6218.55 us544 KBAcceptedScore: 4

Testcase #7243.13 us576 KBAcceptedScore: 4

Testcase #8234.94 us544 KBAcceptedScore: 4

Testcase #9727.72 us668 KBAcceptedScore: 4

Testcase #10549.99 us604 KBAcceptedScore: 4

Testcase #111.131 ms580 KBAcceptedScore: 4

Testcase #121.571 ms824 KBAcceptedScore: 4

Testcase #131.577 ms852 KBAcceptedScore: 4

Testcase #144.348 ms1 MB + 408 KBAcceptedScore: 4

Testcase #157.114 ms1 MB + 856 KBAcceptedScore: 4

Testcase #168.884 ms2 MB + 284 KBAcceptedScore: 4

Testcase #179.798 ms900 KBAcceptedScore: 4

Testcase #1813.702 ms3 MB + 156 KBAcceptedScore: 4

Testcase #1916.44 ms3 MB + 604 KBAcceptedScore: 4

Testcase #2020.117 ms4 MB + 336 KBAcceptedScore: 4

Testcase #2122.326 ms4 MB + 480 KBAcceptedScore: 4

Testcase #2218.454 ms1 MB + 188 KBAcceptedScore: 4

Testcase #239.558 ms1 MB + 548 KBAcceptedScore: 4

Testcase #2419.16 ms1 MB + 232 KBAcceptedScore: 4

Testcase #2523.01 ms4 MB + 924 KBAcceptedScore: 4


Judge Duck Online | 评测鸭在线
Server Time: 2026-11-02 16:43:17 | Loaded in 2 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠