提交记录 120392


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_codex_6a_agg3 noi17a. 【NOI2017】整数 Accepted 100 23.332 ms 4540 KB C++17 48.43 KB
提交时间 评测时间
2026-10-02 18:43:18 2026-10-02 18:43:26
/* 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: Reduce buffered operation chunks from 512 KiB to 32 KiB so parsing and
execution consume their shared operation buffer from L1 cache. 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 the cache-resident operation buffer with paired parsing.
*/
// ===== 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")
#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 4096
#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 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 __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;                    // markRange(c1,c2,S) fixes nfx/nex right after
      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);
}

// 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;                    // markRange(c1,c2,S) fixes nfx/nex right after
      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);
}

// 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) {
  u64 fill = (S == ST_E) ? ~0ULL : 0ULL, ifill = ~fill;
  int w0 = cA >> 6, w1 = cB >> 6, bA = cA & 63, bB = cB & 63;
  u64 fbA = (u64)(D.nfw[cA] != 0), ebA = (u64)(D.newc[cA] != 0);
  u64 fbB = (u64)(D.nfw[cB] != 0), ebB = (u64)(D.newc[cB] != 0);
  if (w0 == w1) {
    u64 m = rangeMask(bA, bB + 1);
    u64 nfb = (fill & ~(1ULL << bA)) | (fbA << bA);
    u64 neb = (ifill & ~(1ULL << bA)) | (ebA << bA);
    nfb = (nfb & ~(1ULL << bB)) | (fbB << bB);
    neb = (neb & ~(1ULL << bB)) | (ebB << bB);
    D.nfx[w0] = (D.nfx[w0] & ~m) | (nfb & m);
    D.nex[w0] = (D.nex[w0] & ~m) | (neb & m);
    return;
  }
  { u64 m = ~0ULL << bA;
    u64 nfb = (fill & ~(1ULL << bA)) | (fbA << bA);
    u64 neb = (ifill & ~(1ULL << bA)) | (ebA << bA);
    D.nfx[w0] = (D.nfx[w0] & ~m) | (nfb & m);
    D.nex[w0] = (D.nex[w0] & ~m) | (neb & m); }
  { u64 m = rangeMask(0, bB + 1);
    u64 nfb = (fill & ~(1ULL << bB)) | (fbB << bB);
    u64 neb = (ifill & ~(1ULL << bB)) | (ebB << bB);
    D.nfx[w1] = (D.nfx[w1] & ~m) | (nfb & m);
    D.nex[w1] = (D.nex[w1] & ~m) | (neb & 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 const 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};
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_castsi128_si256(_mm_load_si128((const __m128i *)(SH10+16*ka)));
  sh=_mm256_inserti128_si256(sh,_mm_load_si128((const __m128i *)(SH10+16*kb)),1);
  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+(u32)(vb>>32)*100000000u;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 = (getBlock((int)(k >> 5)) >> (k & 31u)) & 1u;
          *(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 = (getBlock((int)(k >> 5)) >> (k & 31u)) & 1u;
          *(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 #18.89 us60 KBAcceptedScore: 4

Testcase #212.77 us60 KBAcceptedScore: 4

Testcase #365.11 us60 KBAcceptedScore: 4

Testcase #495.87 us60 KBAcceptedScore: 4

Testcase #575.7 us60 KBAcceptedScore: 4

Testcase #6186.41 us64 KBAcceptedScore: 4

Testcase #7212.86 us96 KBAcceptedScore: 4

Testcase #8203.02 us64 KBAcceptedScore: 4

Testcase #9691.96 us188 KBAcceptedScore: 4

Testcase #10519.45 us124 KBAcceptedScore: 4

Testcase #111.104 ms100 KBAcceptedScore: 4

Testcase #121.536 ms344 KBAcceptedScore: 4

Testcase #131.54 ms372 KBAcceptedScore: 4

Testcase #144.337 ms952 KBAcceptedScore: 4

Testcase #157.076 ms1 MB + 376 KBAcceptedScore: 4

Testcase #168.991 ms1 MB + 828 KBAcceptedScore: 4

Testcase #179.685 ms420 KBAcceptedScore: 4

Testcase #1813.879 ms2 MB + 700 KBAcceptedScore: 4

Testcase #1916.719 ms3 MB + 124 KBAcceptedScore: 4

Testcase #2020.037 ms3 MB + 880 KBAcceptedScore: 4

Testcase #2122.467 ms4 MBAcceptedScore: 4

Testcase #2218.303 ms732 KBAcceptedScore: 4

Testcase #239.697 ms1 MB + 68 KBAcceptedScore: 4

Testcase #2419.041 ms776 KBAcceptedScore: 4

Testcase #2523.332 ms4 MB + 444 KBAcceptedScore: 4


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