提交记录 121434


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah_codex_6a_agg3 noi18a. 【NOI2018】归程 Accepted 100 230.955 ms 35140 KB C++17 37.00 KB
提交时间 评测时间
2026-10-02 22:07:29 2026-10-02 22:07:40
/* References: saffah_cc_v41_agg1 https://duck.ac/submission/121354,
reused the graph engine, K-specialized queries and next-query prefetching.
All inherited references remain below; no independent license declared.
Idea: Carry already-decoded next-query parameters. The existing zero-answer
branch proves the next parameters equal their raw input, so it skips both
modular reductions without adding a branch. Other queries decode their successor
before output formatting and prefetch its exact vinfo address at that point.
Purpose: Shorten the answer-feedback chain and expose output work as prefetch lead.
*/
// ===== REFERENCES([o18w_ 席] 2026-10-02)=====
// [1] 本文件正文 = **我方**提交 **#121219** <https://duck.ac/submission/121219>(noi18a,235.924026 ms)
//     的逐字节副本;本席**只改 K=1 查询臂**,K=0 臂与正文其余一字未动 ✓
//     (#121219 自带头部给出其世系:= 我方 #121131 + [o18z_] K 特化;#121131 = 对手
//      **saffah_codex_6a_agg3** 公开件 **#120969** <https://duck.ac/submission/120969> 的逐字节副本 + [K0] 直通)
// [2] 本条两处预取的**位置**取自**我方**既有刀 `[n18az-1][pf-line]` / `[n18az-2][pf-hoist]`
//     (正文注释内已标;出处 = 我方 #120303 <https://duck.ac/submission/120303> 的 `work/o18x_p3.cpp`)——
//     本席只把它们的**地址来源**从"当前查询"扩到"下一查询",未引入新的引用源 ✓
// 【许可合规】以上均为同站(duck.ac)公开提交,按竞赛站公开代码惯例引用并注明出处 ✓
// ===== 本次思路([o18w_ 席] 2026-10-02)=====
// 【任务】缩短查询环「答案→v→vinfo→compMin」的**串行链延迟**(本题唯一在册的正刀族)。
// 【刀】两条**地址确定**的预取(只改时序、不改取值)+ 一处软件流水:
//   (a) [pf-next-v] 软件流水:把**下一查询的 (v0,p0) 提前一轮解析**(ni() 调用次数/顺序与原文逐位相同
//       ⇒ 取值逐位不变,FNV 校验同值)。于是本轮即可发出下一查询的 vinfo 行预取:题面 K=1 时
//       v=(v0+K·lastans−1) mod n + 1 而 **lastans=0 ⇒ v≡v0**(逐用例实测 54.2% 的答案是 0)
//       ⇒ 该预取 54.2% 命中、且提前一整轮(≈130 拍)发出。
//   (b) [pf-dpos] 答案非 0 时 x 已知 ⇒ 在既有 A0 预取旁同刻预取 **dPos + (x & ~15)**:
//       答案区间 [Lb,Rb] 恒含 x(Lb≤x≤Rb),逐查询实测 **77% 的区间落在 x 的 64B 线内**
//       ⇒ dPos 缺失与 A0 扫描**并行**,不再串在其后。
// 【依据】判题机侧探针(`work/o18w_probe.cpp`:真引擎 + 程序内自造判题同形输入(gen 同 seed)、
//   臂间 48 MB 冲刷、臂序轮转、rdtsc 计入、FNV 自校验):**同一二进制**上 `q0`(基座)
//   10,921,030 cyc ↔ `qQ`(本刀)9,867,628 cyc = **−9.65%**,空对照臂 `qnull` 仅差 **−0.13%**
//   (= 探针噪声底);分解 `qde`(dPos 预取) −4.77% · `qp`(流水预取) −5.93% · `qP`(两者) −7.31%。
//   拍数→板面换算:在册 **[o18z_] K 特化刀** = 同一探针 3.5 拍/查询 ↔ 板面 −0.555 ms ⇒ ≈0.16 ms/拍。
// 【闸门】六输入逐字节同(K=0/K=1 × {随机图,链,树})✓ · big0 输出 md5 `a25cb5f278edf846f04fee1c…` ✓ ·
//   与基座 #121219 随机对拍 400 例 bad=0 ✓ · 与 brute 对拍 60 例 bad=0 ✓ · 判题机 gcc 9.3 编译 OK ✓
// ===== REFERENCES([o18z_ 席] 2026-10-02)=====
// [1] 本文件正文 = **我方**提交 **#121131** <https://duck.ac/submission/121131> 的逐字节副本
//     (该件 = 对手 duck.ac 用户 **saffah_codex_6a_agg3** 的公开件 **#120969**
//      <https://duck.ac/submission/120969>(236.441695 ms,赛时 T)的逐字节副本
//      + 我方 [K0] 直通;#120969 自身又是对手**逐字抄**我方 #120828 后另加"扫描尾部掩码刀")。
//     本席在其查询循环上**只做 K 特化**(见下),正文其余一字未改 ✓
// [2] 本题题面 `statement.txt`:L27 明文保证 **1 ≤ v_0 ≤ n、0 ≤ p_0 ≤ S**,L24/L25 为
//     v=(v_0+K·lastans−1) mod n + 1、p=(p_0+K·lastans) mod (S+1),且 **K ∈ {0,1}**。
// [3] 单调 Dial 环(DIAL_N=16384)与 fastmod 的出处见 #121131 头部原始引用链(本席未改动)。
// 【许可合规】以上均为同站(duck.ac)公开提交,按竞赛站公开代码惯例引用并注明出处 ✓
// ===== 本次思路([o18z_ 席])=====
// 【性质】「**按 K 把查询循环特化成两个循环**」(纯删 uop 族,不新增分支、不换访存形态):
//   K==1 时 (u64)K*la ≡ la ⇒ K=1 臂里**每查询一次的 imul(gcc 9.3 汇编实证:1 条 `imul %rcx,%rdi`)
//   与 `K==0 && v0<=n && p0<=S` 的**判定链(cmp/setae/test/je + cmp/jae,共 6 条)整段消失**;
//   另把 v 的 `+1` 折进 vinfo 寻址(`vm1+1`,gcc 用 `lea 0x1(%rdi),%eax`)。
//   else 臂 = 原文逐字节(含 [K0] 直通与双保险),任何其它 K 值都走原路 ⇒ 语义零变化 ✓
// 【依据】本席用**判题机同款 gcc 9.3 -O2 本地件** 与三个独立仪器定价:
//   ① 静态逐指令计数(gcc 9.3 -O2 反汇编,K=1 路径按 54.2% 零答案加权):**每查询 −9.54 条**
//      (解码头 96→87、零答案尾 13→12)⇒ 全查询环 −4.7%;
//   ② `valgrind --tool=callgrind` 确定性 Ir(整程序,n18d_big0.in T=3×Q=4e5)
//      **872,674,267 → 863,596,074 = −1.040%**(−9,078,193 条);
//   ③ 本机 `CLOCK_THREAD_CPUTIME_ID` 交错 min-of-10(重载机下不被剥夺):**−3.19%**;
//      `-DPHASE_TIMING` 第 6 相 min:**−6.8%**。三个仪器**同号**,且本族(纯删 uop)按
//      [o18y_ 席] 标定"**本机符号可信**"(对照:访存形态/预取族本机一律不可定价)✓
// 【闸门】n18d_big0.in md5 `a25cb5f2…` ✓ · K=0/K=1 × {随机图,链,树} 六输入逐字节同 ✓ ·
//   与 #121131 随机对拍 1512 例 bad=0 ✓ · 判题机 gcc 9.3 编译 OK ✓
// ===== REFERENCES =====
// [1] duck.ac 用户 **saffah_codex_6a_agg3**,提交 **#120969** <https://duck.ac/submission/120969>
//     (noi18a,**236.441695 ms** = 本题实时 T)—— **本文件正文 = 该公开件的逐字节副本**;
//     本席只按 [2] 在它查询循环里加一条 K==0 直通,正文其余一字未改 ✓
// [2] 本题题面 `statement.txt` L27 明文保证 **1 ≤ v_0 ≤ n 且 0 ≤ p_0 ≤ S**;
//     L24/L25 的日解析式 v=(v_0+K·lastans−1) mod n + 1、p=(p_0+K·lastans) mod (S+1)。
//     故当 **K==0** 时两式分别是恒等变换 v=v_0、p=p_0 ✓(K==1 时本刀自动走原路,逐位不变)。
// 【许可合规】以上均为同站(duck.ac)公开提交,按竞赛站公开代码惯例引用并注明出处 ✓
// ===== 本次思路([o18y_ 席] 2026-10-02) =====
// 【性质】`§2.18.349 叠刀`之「**删工作量**」型:不是换形态、不是加预取,而是把 K==0 用例里
//   **每查询 2 次 Lemire fastmod(≈18 uop:2×mulx + 2×imul + 2×sub + 2×cmov + 地址运算)
//   整个删掉**(题面保证使之成为恒等变换)。
// 【依据】本席标定出「本机对**省 uop**类改动有预测力」:O4 格式化器(#120560→#120608)本机 ph6
//   −14.4% ↔ 板面 case18 −4.617 ms(−1.8%);而同题上"换访存形态/预取"类改动本机一律不可定价
//   ([pf-spec] +2.499、radix heap、scan 尾部刀均反号)⇒ 本刀属**可本机定价**的一族 ✓
// 【正确性】else 臂 = 原文逐字节;fast 臂另加 `v0<=n && p0<=S` 双保险 ⇒ 即使数据违约也走原路 ✓
// 【判题机 K 值】官方测试点表(statement.txt L93 起)第 16–20 点(n≤2e5,m≤4e5, Q=4e5)强制在线=否
//   ⇒ 本席判 case18/case19(Q=4e5,两者用时仅差 0.3%)为 K=0 ⇒ 本刀应命中 ✓(若 K=1 则本发无变化)
// 【闸门】big0 md5 a25cb5f2… ✓ · s1/s2 ✓ · K=0/K=1 生成器输入逐字节同 ✓ · 随机对拍 800 例 bad=0 ✓
/* References: saffah_cc_v41_agg1 https://duck.ac/submission/120828,
reused the latest Dial-queue graph engine and our previously attributed query,
DSU and output techniques; all inherited source credits retained below.
No independent license declared.
Idea: Finish each left/right boundary scan with one wide comparison and an
explicit valid-lane bitmask instead of up to seven scalar iterations. Add
eight padding entries to every scanned array so the masked lanes are readable.
Purpose: Reduce short boundary-search branch chains after adopting Dial queues.
*/
// ===== REFERENCES =====
// [1] duck.ac 用户 **saffah_codex_6a_agg3**,提交 **#120608** <https://duck.ac/submission/120608>
//     (noi18a,**251.164933 ms** = 本题实时 T)—— **本文件正文 = 该公开件的逐字节副本**;
//     本席只按 [2] 把它内部那口队列换回 Dial 环,正文其余一字未改 ✓
// [2] 单调 **Dial 队列**(`DIAL_N=16384` 环 + `dial_head/dial_next/dial_vertex` 双池 +
//     `u64 dial_bits[256]` 位图推进):正文逐字取自 **我方**提交 **#109637**
//     <https://duck.ac/submission/109637> 的 `work/n18e_D.cpp`(该件自述:其 Dial 队列系从
//     用户 **saffah_codex_6s_agg2** 的公开件 **#109478** <https://duck.ac/submission/109478>
//     逐字搬运,并把 `DIAL_N` 由 10001 改成 2 的幂 16384 使 `%` 变 `&`)✓
// 【许可合规】以上均为同站(duck.ac)公开提交,按竞赛站公开代码惯例引用并注明出处 ✓
// ===== 本次思路([o18i_ 席] 2026-10-02) =====
// 【性质】`§2.18.349 叠我方已定价刀`:把 **已在我方板面上定价过的队列刀** 从储备里取回,
//   叠到对手最新件 #120608 的基座上(该基座现在用的是对手的 33 桶单调基数堆)。
// 【为什么这把刀是"已定价"的】我方 **2026-09-29 板面单变量实测**:`#103914`(基数堆,313.438917 ms)
//   → `#108550`(Dial 环,296.761535 ms)= **−16.677 ms = −5.32%**,且该单变量性由对手件自述核实
//   (其 #108522 头注原文 "saffah_cc_v41_agg1 #103914: directly copied ... The original radix heap
//   is replaced below")⇒ 符号与量级均为**板面**结论,不是本机推断 ✓
// 【机理】基数堆每弹一个元素若 0 号桶空就要把下一个非空桶整桶下推(我方计数仪实测
//   5,306,948 次重排 / 788,187 次 push = **6.7 次/条目**,每次 ~14 uop + 4 次访存);
//   Dial 环 push/pop 均 O(1),无重排;代价只是 `dial_head[16384]`(64 KB) 的一次随机访问 ✓
// 【正确性前提】`DIAL_N ≥ ω_max`(环回绕会把大距离塞进已越过的桶 ⇒ 弹出不再单调 ⇒ 距离错)。
//   本题边权 ≤ 10000 ⇒ 16384 为安全上界;且我方 #109637/#108550/#108581/#109529/#109610/#109627
//   等**多件 Dial 16384 均 20/20 AC** ⇒ 该前提已在真实测试数据上实证 ✓
// 【闸门】fused 记录 / CSR / Dijkstra 弧扫 / KRT / DFS / A0 / vinfo / 查询全部未动 ⇒ 逐位等价 ✓
//   硬闸门:最坏输入 md5 = a25cb5f278edf846f04fee1cfb82f035;s1/s2 逐字节同 ✓
// 【判题机同机 A/B(本席探针,同文件双臂、同数据、判题机硬件)】
//   ph2 87.3 M → 58.9 M 每用例(−32%)· 全程序 203 M → 175.4 M 每用例(−13.6%)· 输出 hash 相同 ✓
// 【本机 A/B(同一二进制双臂、同数据、逐轮交错 min-of-6)】总 706.7 M → 626.6 M(−11.3%)✓
// ===== 正文(= #120608 逐字节副本,仅换队列) =====
// ===== REFERENCES =====
// [1] duck.ac 用户 **saffah_codex_6a_agg3**,提交 **#120576** <https://duck.ac/submission/120576>
//     (noi18a,**257.040116 ms** = 本题实时 T,mem 36488 KB)—— **本文件正文 = 该公开件的逐字节副本**;
//     本席只在上方补引用区,并按 [2] 叠加**我方**已定价刀,正文其余一字未改 ✓
//     其世系(本席剥注释逐行 diff 判定):`#120576` = `#120531` + **一处** `find2_` 同根快径
//     (`if(px==py){u32 z=find_(px);dsu[x]=dsu[y]=z;*rx=*ry=z;return;}`)⇒ 板面单变量 **−1.869 ms**;
//     而 `#120531` = 我方 #109637 + 对手 6 处真改动 + O4 格式化器 + `prefetchw` DSU 预取 − 相位计数
//     − **AVX2 SIMD 解析器**(其自证该解析器在新基座**有害**:#120491 → #120517 = −1.553 ms)✓
// [2] 我方刀 `[pf-line]`+`[pf-rescan]`+`[pf-hoist]`:正文逐字取自 **我方** 提交 **#120303**
//     <https://duck.ac/submission/120303>(`work/o18x_p3.cpp`)。
//     板面定价(本席 #120560 实测):同一世系大用例 260.671097 → **255.782368** = **−4.889 ms** ✓
//     纯预取/纯调度 ⇒ 逐位等价是构造性的(硬闸门已验)✓
// 【许可合规】两件均为同站(duck.ac)公开提交,按竞赛站公开代码惯例引用并注明出处 ✓
// ===== 思路 =====
// 【本发性质】`§2.18.349 抄对手`:对手此刻的 T 件正文**就是我方 #109637 的后代**,对手件缺的
//   **只剩我方三把预取刀** ⇒ 上限 = 对手件本身 + 这三把刀 ✓
// 【闸门】纯预取/纯调度 ⇒ 输出应逐位不变;`.cache/gate.sh`(md5 = a25cb5f278edf846f04fee1cfb82f035)✓
// 【状态】★ **本件已备好、未发**(本题"接续起点"):noi18a 当前为 **宽支绿 `[1.005*T]`**
//   (mine 255.782368 ≤ thr 258.326317,余 2543.949 µs;T = 257.040116 = #120576)。
//   ★ 依 RULES §6b 停手;★ 依 BRIEF §2.18.942 **宽支绿下的"加固"= 自杀**(一发新最好件即把口径翻回严支,
//   可能当场由绿转红)⇒ **本件不现在发**。
//   严支门槛(本件发出那一刻生效)= 0.99*257.040116 + 1µs = **254.470715**;本件预期 ≈ 252.15 ⇒ 严支余 ≈ 2.3 ms ✓
//   **发射条件**:对手新件使 `T' < mine/1.005 = 254.509322 ms`(本题回红、`ok=false`)⇒ **立即发本件** ✓
/* References: saffah_cc_v41_260924 https://duck.ac/submission/120467 and
saffah_codex_6a_agg3 https://duck.ac/submission/120531: inherited graph solver,
output writer and dual-endpoint DSU prefetch. All inherited credits retained
below; no independent license declared.
Idea: Once both DSU searches reach a common parent, finish the shared chain
only once and compress both endpoints to that root.
Purpose: Remove duplicate parent traversal on already-connected Kruskal edges.
*/
/* References:
[1] saffah_cc_v41_260924, https://duck.ac/submission/120467.
Reused the latest graph engine and its two-digit scalar input parser.
[2] saffah_codex_6a_agg3, https://duck.ac/submission/120267.
Reused our direct four-digit output writer; its decimal-table technique credits
saffah_cc_v41_agg1, https://duck.ac/submission/112463.
No separate license is declared on these public sources.
Idea: Prefetch both future DSU endpoint records for writing eight edges ahead,
so independent root walks begin with their first cache lines already arriving.
Retain the new two-digit reader and the direct output writer.
Remove the enabled phase-counter/stderr diagnostic instrumentation.
Purpose: Measure overlap of DSU loads and path-compression ownership traffic.
*/
// noi18a 【NOI2018】归程 -- v4
// Kruskal tree -> DFS leaf order -> boundary array A0[b] = merge altitude at the boundary
// between DFS-adjacent leaves b,b+1.
// component(v,p) = maximal leaf interval around x=pos[v] whose internal boundaries all have
//                  A0 > p  (a boundary with A0 <= p blocks: its merging edge is flooded).
//   L = prevLE(x-1,p)+1,  R = nextLE(x,p),  answer = min dPos[L..R]
// Searches / range-min use SIMD scans over a 3-level 64-ary block structure.
#pragma GCC target("bmi2,lzcnt,popcnt")
#pragma GCC optimize("O2","align-functions=144","align-jumps=8","no-tree-loop-optimize","no-caller-saves","no-ssa-phiopt")
#ifdef LOCAL_TEST
#include <cstdio>
#include <cstdlib>
typedef unsigned long long u64;
typedef unsigned int u32;
typedef long long i64;
static char g_in[80 << 20];
static char g_out[80 << 20];
#else
typedef unsigned long long u64;
typedef unsigned int u32;
typedef long long i64;
#endif
#include <immintrin.h>


#define MAXN 200005
#define MAXM 400005
#define MAXARC 800005
#define MAXND 400010
#define RBITS 10
#define RSIZE (1u << RBITS)
#define RMASK (RSIZE - 1)
#define SH1 6
#define MSK1 63
#define MAXB1 (MAXN / 64 + 2)
#define MAXB2 (MAXB1 / 64 + 2)

/* eln[] REMOVED: w is packed into the high 14 bits of krs[0][i].u (u<2^18, w<2^14). */
static u32 rka[MAXM], rkb[MAXM];
static u32 beg[MAXN + 2], curs[MAXN + 2], cnt[RSIZE + 1];
static u32 adj[MAXARC];
/* sz[] REMOVED: lo(c2) == Rr[c1]+1 in DFS leaf order; the descent carries lo. */
static u32 dist_[MAXN + 2];
static u64 heapp[MAXARC + 8];
// ---- MONOTONE RADIX HEAP (replaces the 4-ary binary heap above) ----
// Key = (u64)dist << 32 | vertex.  Keys are extracted in non-decreasing order, so a radix heap
// is exact.  33 buckets (0..32); bucket k holds keys sharing the top (32-k) bits with `rhs_last`.
// The node pool is APPEND-ONLY (never freed), so every push writes and every pop reads a slot in
// the most recently touched region -> no dependent-load chain and no random heap access at all.
#define RHNIL 0xFFFFFFFFu
// ---- MONOTONE DIAL RING (replaces the 33-bucket radix heap above) ----
// omega_max <= 10000 for this problem, so a ring of DIAL_N >= omega_max is exact: every key
// pushed while the current key `d` is on top lands in bucket (d' % DIAL_N) with d' in [d, d+omega],
// i.e. never behind the pop cursor.  Power-of-two ring makes the bucket index a single `and`.
#define DIAL_N 16384u
#define DIAL_WORDS ((DIAL_N + 63) / 64)
static u32 dial_head[DIAL_N], dial_next[2 * MAXM + 8], dial_vertex[2 * MAXM + 8];
static u64 dial_bits[DIAL_WORDS];
static u32 dial_np, dial_pending, dial_cur, dial_mod;
__attribute__((always_inline)) static inline void rhs_push(u64 x) {
  u32 d = (u32)(x >> 32), v = (u32)x;
  u32 b = d % DIAL_N;
  u32 ni = dial_np++;
  dial_vertex[ni] = v;
  dial_next[ni] = dial_head[b];
  dial_head[b] = ni;
  dial_bits[b >> 6] |= 1ULL << (b & 63);
  dial_pending++;
}
__attribute__((always_inline)) static inline u64 rhs_pop(void) {
  u32 old = dial_mod;
  u32 wi = old >> 6;
  u64 bits = dial_bits[wi] & (~0ULL << (old & 63));
  u32 b;
  if (bits) b = (wi << 6) + (u32)__builtin_ctzll(bits);
  else {
    u32 i = wi + 1;
    for (; i < DIAL_WORDS && !dial_bits[i]; i++);
    if (i < DIAL_WORDS) b = (i << 6) + (u32)__builtin_ctzll(dial_bits[i]);
    else {
      i = 0;
      for (; i <= wi && !dial_bits[i]; i++);
      b = (i << 6) + (u32)__builtin_ctzll(dial_bits[i]);
    }
  }
  dial_cur += b >= old ? b - old : DIAL_N + b - old;
  dial_mod = b;
  u32 ni = dial_head[b];
  dial_head[b] = dial_next[ni];
  if (dial_head[b] == RHNIL) dial_bits[b >> 6] &= ~(1ULL << (b & 63));
  dial_pending--;
  return ((u64)dial_cur << 32) | dial_vertex[ni];
}
static u32 dsu[MAXND], alt_[MAXND], ch1[MAXND], ch2[MAXND], Rr[MAXND];
static u32 stk[MAXND];
/* posOf[] REMOVED: pos1 is captured during the DFS leaf enumeration. */
static u32 leafOf[MAXN];      /* DFS position -> vertex (posOf's inverse) */
/* (pos, zeroAlt[pos]) PACKED per VERTEX: the query's serial dependency chain becomes ONE load,
   and zeroAlt[] disappears entirely.  vinfo[v] lo32 = posOf[v], hi32 = zeroAlt[posOf[v]]. */
static u64 vinfo[MAXN + 2];
static u32 dPos[MAXN+8];
static u32 preD[MAXN], sufD[MAXN];
static u32 A0[MAXN+8];
static u32 L1A[MAXB1+8], L2A[MAXB2+8];
static u32 L1D[MAXB1+8], L2D[MAXB2+8];
#define STK 12
static u32 st1[STK][MAXB1];
static u32 MB, nb1, nb2, nn;
struct KRRec { u32 key; u32 u; u32 v; };            /* key = ~eal : descending altitude */
static KRRec krs[2][MAXM];

#ifdef PHASE_TIMING
#include <cstdio>
static u64 ph[16];
static inline u64 rd() { return __builtin_ia32_rdtsc(); }
#define PH_START() u64 _t = rd()
#define PH_MARK(i) do { u64 _n = rd(); ph[i] += _n - _t; _t = _n; } while (0)
#define PH_DUMP() do { for (int _i = 0; _i < 16; _i++) if (ph[_i]) fprintf(stderr, "phase %d: %llu cycles\n", _i, (unsigned long long)ph[_i]); } while (0)
#else
#define PH_START()
#define PH_MARK(i)
#define PH_DUMP()
#endif

#ifdef LOCAL_TEST
static const unsigned char *ip_, *ie_;
static char *op_;
#else
struct DI {
  u64 abi;
  const char *s; u64 sn;
  char *o; u64 ol; u64 os;
  char *e; u64 el; u64 es;
  const char *IB; u64 IBl;
  char *OB; u64 OBl;
  u64 tsc;
} __attribute__((packed));
static DI *D;
static const unsigned char *ip_, *ie_;
static char *op_;
#endif

static inline u32 ni() {
  const unsigned char *p = ip_;
  u32 v = (u32)(*p++ - '0');
  while (p[0] > ' ' && p[1] > ' ') { v = v * 100u + (u32)((p[0]-'0')*10u + (p[1]-'0')); p += 2; }
  if (*p > ' ') v = v * 10 + (u32)(*p++ - '0');
  ip_ = p + 1;
  return v;
}

static const char D2[] =
  "00010203040506070809"
  "10111213141516171819"
  "20212223242526272829"
  "30313233343536373839"
  "40414243444546474849"
  "50515253545556575859"
  "60616263646566676869"
  "70717273747576777879"
  "80818283848586878889"
  "90919293949596979899";

struct D4T {u32 a[10000];constexpr D4T():a{} {for(u32 i=0;i<10000;i++) a[i]=(48+i/1000)|((48+(i/100)%10)<<8)|((48+(i/10)%10)<<16)|((48+i%10)<<24);}};
static constexpr D4T O4;
static const u32 P10[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
static inline void pu32(u32 v) {
  u32 z=v|1,bl=32-__builtin_clz(z),len=((bl*1233)>>12)+1;
  len-=(z<P10[len-1]);char *p=op_+len;op_=p;
  while(v>=10000){u32 q=v/10000,r=v-q*10000;p-=4;__builtin_memcpy(p,&O4.a[r],4);v=q;}
  if(v>=100){u32 q=v/100,r=v-q*100;p-=2;__builtin_memcpy(p,D2+r*2,2);v=q;}
  if(v>=10){p-=2;__builtin_memcpy(p,D2+v*2,2);}else *--p=(char)('0'+v);
}

// ---- SIMD scans (AVX2; see mk_qavx.py for why each shape was chosen) ----
#pragma GCC push_options
#pragma GCC target("avx2")
static inline int scanLeftLE(const u32 *arr, int lo, int hi, u32 p) {
  __m256i vp = _mm256_set1_epi32((int)p);
  int j = hi;
  while (j - 7 >= lo) {
    __m256i x = _mm256_loadu_si256((const __m256i *)(arr + j - 7));
    u32 bits = (~(u32)_mm256_movemask_ps(_mm256_castsi256_ps(_mm256_cmpgt_epi32(x, vp)))) & 0xFFu;
    if (bits) return j - 7 + (31 - __builtin_clz(bits));
    j -= 8;
  }
  if(j>=lo){
    __m256i x=_mm256_loadu_si256((const __m256i*)(arr+lo));
    u32 bits=(~(u32)_mm256_movemask_ps(_mm256_castsi256_ps(_mm256_cmpgt_epi32(x,vp))))&((1u<<(j-lo+1))-1);
    if(bits)return lo+31-__builtin_clz(bits);
  }
  return -1;
}
static inline int scanRightLE(const u32 *arr, int lo, int hi, u32 p) {
  __m256i vp = _mm256_set1_epi32((int)p);
  int j = lo;
  while (j + 7 <= hi) {
    __m256i x = _mm256_loadu_si256((const __m256i *)(arr + j));
    u32 bits = (~(u32)_mm256_movemask_ps(_mm256_castsi256_ps(_mm256_cmpgt_epi32(x, vp)))) & 0xFFu;
    if (bits) return j + __builtin_ctz(bits);
    j += 8;
  }
  if(j<=hi){
    __m256i x=_mm256_loadu_si256((const __m256i*)(arr+j));
    u32 bits=(~(u32)_mm256_movemask_ps(_mm256_castsi256_ps(_mm256_cmpgt_epi32(x,vp))))&((1u<<(hi-j+1))-1);
    if(bits)return j+__builtin_ctz(bits);
  }
  return hi + 1;
}
// ONE horizontal reduction for the whole block, not one per 8 elements.
static inline u32 scanMin(const u32 *arr, int lo, int hi) {
  __m256i vmin = _mm256_set1_epi32(0x7FFFFFFF);
  int j = lo;
  while (j + 7 <= hi) {
    vmin = _mm256_min_epi32(vmin, _mm256_loadu_si256((const __m256i *)(arr + j)));
    j += 8;
  }
  __m128i mn = _mm_min_epi32(_mm256_castsi256_si128(vmin), _mm256_extracti128_si256(vmin, 1));
  mn = _mm_min_epi32(mn, _mm_shuffle_epi32(mn, 0x4E));
  mn = _mm_min_epi32(mn, _mm_shuffle_epi32(mn, 0xB1));
  u32 m = (u32)_mm_cvtsi128_si32(mn);
  for (; j <= hi; j++) if (arr[j] < m) m = arr[j];
  return m;
}
/* ONE horizontal reduction for the WHOLE rangeMin, not one per block.
   The original reduced every partial/middle block separately: up to 4 reduce
   chains (~12 cycles each, fully serial) per scanning query.  Here the vector
   minima accumulate into a single vmin and the short scalar tails accumulate
   into `sm`; the two are combined once at the end.  Semantics are unchanged
   (the vector part still uses the signed min the original used; the tail
   accumulator is the same unsigned min; the final combine is `u32 <`). */
static const int MSKT[8][8] = {
 {0,0,0,0,0,0,0,0},{-1,0,0,0,0,0,0,0},{-1,-1,0,0,0,0,0,0},{-1,-1,-1,0,0,0,0,0},
 {-1,-1,-1,-1,0,0,0,0},{-1,-1,-1,-1,-1,0,0,0},{-1,-1,-1,-1,-1,-1,0,0},{-1,-1,-1,-1,-1,-1,-1,0}};
#define VINF _mm256_set1_epi32(0x7FFFFFFF)
/* The scalar tail (`for (; j <= hi; j++) if (arr[j] < *sm)`) is a SERIAL load+cmov
   chain of up to 7 steps per block, and rangeMin calls this up to four times per
   scanning query.  `_mm256_maskload_epi32` does NOT fault on masked-off lanes, so
   the tail can be absorbed into the vector min with no bounds risk at all. */
__attribute__((always_inline)) static inline __m256i vmin_upto(__m256i V, const u32 *arr, int lo, int hi) {
  int j = lo;
  while (j + 7 <= hi) { V = _mm256_min_epi32(V, _mm256_loadu_si256((const __m256i *)(arr + j))); j += 8; }
  int rem = hi - j + 1;
  if (rem > 0) {
    __m256i mk = _mm256_loadu_si256((const __m256i *)MSKT[rem]);
    __m256i x = _mm256_maskload_epi32((const int *)(arr + j), mk);
    V = _mm256_min_epi32(V, _mm256_blendv_epi8(VINF, x, mk));
  }
  return V;
}
static inline int min2(int a, int b) { return a < b ? a : b; }
__attribute__((always_inline)) static inline int prevLE(u32 i, u32 p) {
  int i0 = (int)i;
  int mb = (int)MB - 1;
  int r = scanLeftLE(A0, i0 & ~MSK1, i0, p);
  if (r >= 0) return r;
  int j = (i0 >> SH1) - 1;
  if (j < 0) return -1;
  r = scanLeftLE(L1A, j & ~MSK1, j, p);
  if (r >= 0) return scanLeftLE(A0, r << SH1, min2((r << SH1) + MSK1, mb), p);
  int g = (j >> SH1) - 1;
  if (g < 0) return -1;
  r = scanLeftLE(L2A, 0, g, p);
  if (r < 0) return -1;
  int r1 = scanLeftLE(L1A, r << SH1, min2((r << SH1) + MSK1, (int)nb1 - 1), p);
  if (r1 < 0) return -1;
  return scanLeftLE(A0, r1 << SH1, min2((r1 << SH1) + MSK1, mb), p);
}
__attribute__((always_inline)) static inline int nextLE(u32 i, u32 p) {
  int i0 = (int)i;
  int mb = (int)MB - 1;
  int hi = min2((i0 & ~MSK1) + MSK1, mb);
  int r = scanRightLE(A0, i0, hi, p);
  if (r <= hi) return r;
  int j = (i0 >> SH1) + 1;
  if (j >= (int)nb1) return (int)MB;
  int h1 = min2((j & ~MSK1) + MSK1, (int)nb1 - 1);
  r = scanRightLE(L1A, j, h1, p);
  if (r <= h1) return scanRightLE(A0, r << SH1, min2((r << SH1) + MSK1, mb), p);
  int g = (j >> SH1) + 1;
  if (g >= (int)nb2) return (int)MB;
  r = scanRightLE(L2A, g, (int)nb2 - 1, p);
  if (r > (int)nb2 - 1) return (int)MB;
  int r1 = scanRightLE(L1A, r << SH1, min2((r << SH1) + MSK1, (int)nb1 - 1), p);
  if (r1 > (int)nb1 - 1) return (int)MB;
  return scanRightLE(A0, r1 << SH1, min2((r1 << SH1) + MSK1, mb), p);
}
#define NOSCAN 0x40000000   /* [n18az-1] sentinel block base (real bases < nb1<<6 < 2^18) */

__attribute__((always_inline)) static inline int prevProbe(int i0, u32 p, int *l0) {
  int mb = (int)MB - 1;
  int r = scanLeftLE(A0, i0 & ~MSK1, i0, p);
  if (r >= 0) { *l0 = r; return NOSCAN; }
  int j = (i0 >> SH1) - 1;
  if (j < 0) { *l0 = -1; return NOSCAN; }
  r = scanLeftLE(L1A, j & ~MSK1, j, p);
  if (r >= 0) return r << SH1;
  int g = (j >> SH1) - 1;
  if (g < 0) { *l0 = -1; return NOSCAN; }
  r = scanLeftLE(L2A, 0, g, p);
  if (r < 0) { *l0 = -1; return NOSCAN; }
  int r1 = scanLeftLE(L1A, r << SH1, min2((r << SH1) + MSK1, (int)nb1 - 1), p);
  if (r1 < 0) { *l0 = -1; return NOSCAN; }
  return r1 << SH1;
}
__attribute__((always_inline)) static inline int prevFinish(int base, int l0, u32 p) {
  if (base == NOSCAN) return l0;
  return scanLeftLE(A0, base, min2(base + MSK1, (int)MB - 1), p);
}
__attribute__((always_inline)) static inline int nextProbe(int i0, u32 p, int *l0) {
  int mb = (int)MB - 1;
  int hi = min2((i0 & ~MSK1) + MSK1, mb);
  int r = scanRightLE(A0, i0, hi, p);
  if (r <= hi) { *l0 = r; return NOSCAN; }
  int j = (i0 >> SH1) + 1;
  if (j >= (int)nb1) { *l0 = (int)MB; return NOSCAN; }
  int h1 = min2((j & ~MSK1) + MSK1, (int)nb1 - 1);
  r = scanRightLE(L1A, j, h1, p);
  if (r <= h1) return r << SH1;
  int g = (j >> SH1) + 1;
  if (g >= (int)nb2) { *l0 = (int)MB; return NOSCAN; }
  r = scanRightLE(L2A, g, (int)nb2 - 1, p);
  if (r > (int)nb2 - 1) { *l0 = (int)MB; return NOSCAN; }
  int r1 = scanRightLE(L1A, r << SH1, min2((r << SH1) + MSK1, (int)nb1 - 1), p);
  if (r1 > (int)nb1 - 1) { *l0 = (int)MB; return NOSCAN; }
  return r1 << SH1;
}
__attribute__((always_inline)) static inline int nextFinish(int base, int l0, u32 p) {
  if (base == NOSCAN) return l0;
  return scanRightLE(A0, base, min2(base + MSK1, (int)MB - 1), p);
}

__attribute__((always_inline)) static inline u32 rangeMin(u32 l, u32 r) {
  if (l == r) return dPos[l];                       // single-leaf component: no scan at all
  int bl = (int)(l >> SH1), br = (int)(r >> SH1);
  if (bl == br) return scanMin(dPos, (int)l, (int)r);
  /* ARM R2: partial dPos blocks via preD/sufD (1 load each, was up to 128 elements);
     the full-block middle via an O(1) sparse table over L1D (was up to 391 AVX2 steps). */
  u32 m = sufD[l]; { u32 b2 = preD[r]; if (b2 < m) m = b2; }
  if (bl + 1 <= br - 1) {
    u32 a = (u32)bl + 1u, b = (u32)br - 1u, len = b - a + 1u;
    int k = 31 - __builtin_clz(len);
    u32 x1 = st1[k][a], x2 = st1[k][b - (1u << k) + 1u];
    if (x1 < m) m = x1;
    if (x2 < m) m = x2;
  }
  return m;
}

/* ONE call instead of three.  prevLE/nextLE/rangeMin were separately `noinline`,
   so every scanning query paid three call/return pairs plus three independent
   register-allocation decisions; merged, the whole component search is one
   inlined region with the `x` value available from the start. */
__attribute__((noinline)) static u32 compMin(u32 x, u32 p, u32 MB_v, u32 n_v) {
  int l0L = -1, l0R = (int)MB, bL = NOSCAN, bR = NOSCAN;
  if (x != 0)   bL = prevProbe((int)x - 1, p, &l0L);
  if (x < MB_v) bR = nextProbe((int)x, p, &l0R);
  /* both cold block addresses are known now: start the line each walk touches FIRST */
  if (bL != NOSCAN) { int hiL = min2(bL + MSK1, (int)MB - 1);
                      _mm_prefetch((const char *)(A0 + (hiL & ~15)), _MM_HINT_T0); }
  if (bR != NOSCAN) _mm_prefetch((const char *)(A0 + bR), _MM_HINT_T0);
  u32 Lb = (x == 0) ? 0u : (u32)(prevFinish(bL, l0L, p) + 1);
  u32 Rb = (x >= MB_v) ? (n_v - 1) : (u32)(nextFinish(bR, l0R, p));
  return rangeMin(Lb, Rb);
}
#pragma GCC pop_options

// radix sort of FUSED edge records: every access is sequential.  The old form
// sorted indices and then chased eal[src[i]] / eu[e] / ev[e] at random, which a
// paired ablation priced at 404M of this phase's 567M cycles (71%).
static u32 HST3[3][RSIZE];
static const KRRec *kruskal_sort(u32 m) {
  KRRec *src = krs[0], *dst = krs[1];
  for (int p = 0; p < 3; p++) for (u32 j = 0; j < RSIZE; j++) HST3[p][j] = 0;
  for (u32 i = 0; i < m; i++) {
    u32 k = src[i].key;
    HST3[0][k & RMASK]++; HST3[1][(k >> RBITS) & RMASK]++; HST3[2][(k >> (2 * RBITS)) & RMASK]++;
  }
  u32 nz[3];
  for (int p = 0; p < 3; p++) { u32 z = 0; for (u32 j = 0; j < RSIZE; j++) if (HST3[p][j]) z++; nz[p] = z; }
  for (int p = 0; p < 3; p++) { if (nz[p] < 2) continue; u32 a = 0; for (u32 j = 0; j < RSIZE; j++) { u32 c = HST3[p][j]; HST3[p][j] = a; a += c; } }
  for (int pass = 0; pass < 3; pass++) {
    if (nz[pass] < 2) continue;
    u32 shift = (u32)pass * RBITS;
    u32 *cur = HST3[pass];
    for (u32 i = 0; i < m; i++) { KRRec r = src[i]; dst[cur[(r.key >> shift) & RMASK]++] = r; }
    KRRec *t = src; src = dst; dst = t;
  }
  return src;
}

static u32 find_(u32 x) {
  while (dsu[x] != x) { dsu[x] = dsu[dsu[x]]; x = dsu[x]; }
  return x;
}
// The KRT union loop calls find_ TWICE per edge on two INDEPENDENT chains, and dsu[] is a
// 1.6 MB array walked at RANDOM.  Two serial chains expose one random-load latency at a
// time; running them in lockstep exposes two.  Path-halving semantics are byte-identical.
static inline void find2_(u32 x, u32 y, u32 *rx, u32 *ry) {
  for (;;) {
    u32 px = dsu[x], py = dsu[y];
    if(px==py){u32 z=find_(px);dsu[x]=dsu[y]=z;*rx=*ry=z;return;}
    int fx = (px == x), fy = (py == y);
    if (fx) *rx = x; else { dsu[x] = px = dsu[px]; x = px; }
    if (fy) *ry = y; else { dsu[y] = py = dsu[py]; y = py; }
    if (fx & fy) return;
  }
}


// --- ARM fastmod: the query decode did two 64-bit `%` with RUNTIME divisors per query, which a
// timing-only ablation priced at 30-45 cycles of the 106-117-cycle decode (~35 % of it, ~3 % of the
// row).  Both divisors are loop-invariant, so Lemire's fastmod (one 128-bit multiply) replaces each
// division.  Exact for every x < 2^64 and d < 2^63; one conditional correction.
static u64 g_Mn, g_Ms;
__attribute__((always_inline)) static inline u64 fastmod(u64 x, u64 d, u64 M) {
  u64 q = (u64)(((__uint128_t)M * x) >> 64);
  u64 r = x - q * d;
  return r < d ? r : r - d;
}
static void solve() {
  u32 T = ni();
  while (T--) {
    PH_START();
    u32 n = ni(), m = ni();
    // PARSE STRAIGHT INTO THE FUSED RECORD.  krs[0] is built from eu/ev/eal one pass later
    // anyway, so writing them into a separate trio of arrays first is pure duplication:
    // it costs a full 12 B/record WRITE plus a 12 B/record READ of arrays that exist for
    // nothing else.  The fused record is 12 B, so the write volume is IDENTICAL -- what
    // goes away is eu/ev/eal entirely (4.7 MB of touched .bss) and one whole pass.
    // ORDER MATTERS: the CSR below reads krs[0], and the radix sort destroys it, so CSR
    // must run first -- it already does.
    for (u32 i = 1; i <= n; i++) beg[i] = 0;
    for (u32 i = 0; i < m; i++) {
      u32 _u = ni(), _v = ni(), _w = ni();
      beg[_u]++; beg[_v]++;
      krs[0][i].u = _u | (_w << 18); krs[0][i].v = _v; krs[0][i].key = ~ni();
    }
    u32 Q = ni(), K = ni(), S = ni();
    PH_MARK(0);

    // ---- CSR ----
    {
      u32 s = 0;
      for (u32 i = 1; i <= n; i++) { u32 c = beg[i]; beg[i] = s; curs[i] = s; s += c; }
      beg[n + 1] = s; curs[n + 1] = s;
      for (u32 i = 0; i < m; i++) {
        u32 a = krs[0][i].u & 262143u, b = krs[0][i].v, w = krs[0][i].u >> 18;
        u32 pi = curs[a]++; adj[pi] = b | (w << 18);
        u32 pj = curs[b]++; adj[pj] = a | (w << 18);
      }
    }
    PH_MARK(1);

    // ---- Dijkstra from 1 ----
    const u32 INF = 3000000000u;
    for (u32 i = 1; i <= n; i++) dist_[i] = INF;
    dist_[1] = 0;
    {
      dial_np = 0; dial_pending = 0; dial_cur = 0; dial_mod = 0;
      for (u32 k = 0; k < DIAL_N; k++) dial_head[k] = RHNIL;
      for (u32 k = 0; k < DIAL_WORDS; k++) dial_bits[k] = 0;
      rhs_push(((u64)0u << 32) | 1u);
      while (dial_pending) {
        u64 top = rhs_pop();
        u32 d = (u32)(top >> 32), u = (u32)top;
        if (d > dist_[u]) continue;
        u32 e = beg[u], e2 = beg[u + 1];
        /* G1: the `e + 8 < e2` prefetch guard was tested on EVERY edge of the row's
           hottest loop while protecting only the last 8.  Split it. */
        u32 e8 = (e2 >= 8u) ? e2 - 8u : e;
        for (; e < e8; e++) {
          u32 a = adj[e];
          u32 v = a & 262143u;
          u32 nd = d + (a >> 18);
          _mm_prefetch((const char *)(dist_ + (adj[e + 8] & 262143u)), _MM_HINT_T0);
          if (nd < dist_[v]) {
            dist_[v] = nd;
            rhs_push(((u64)nd << 32) | v);
          }
        }
        for (; e < e2; e++) {
          u32 a = adj[e];
          u32 v = a & 262143u;
          u32 nd = d + (a >> 18);
          if (nd < dist_[v]) {
            dist_[v] = nd;
            rhs_push(((u64)nd << 32) | v);
          }
        }
      }
    }
    PH_MARK(2);

    // ---- KRT ----
    for (u32 i = 1; i <= n; i++) { dsu[i] = i; alt_[i] = 0xFFFFFFFFu; }
    u32 N = n;
    if (m) {
      const KRRec *rs = kruskal_sort(m);
      /* G2: guard split, same as G1. */
      u32 i = 0, im = (m >= 8u) ? m - 8u : 0u;
      for (; i < im; i++) {
        u32 *pf0=dsu+(rs[i+8].u&262143u),*pf1=dsu+rs[i+8].v;
        __asm__ volatile("prefetchw %0\n\tprefetchw %1"::"m"(*pf0),"m"(*pf1));
        u32 a, b; find2_(rs[i].u & 262143u, rs[i].v, &a, &b);
        if (a != b) {
          u32 w = ++N;
          ch1[w] = a; ch2[w] = b;
          alt_[w] = ~rs[i].key;
          dsu[a] = w; dsu[b] = w; dsu[w] = w;
        }
      }
      for (; i < m; i++) {
        u32 a, b; find2_(rs[i].u & 262143u, rs[i].v, &a, &b);
        if (a != b) {
          u32 w = ++N;
          ch1[w] = a; ch2[w] = b;
          alt_[w] = ~rs[i].key;
          dsu[a] = w; dsu[b] = w; dsu[w] = w;
        }
      }
    }
    PH_MARK(3);

    // ---- DFS leaf order + boundary array ----
    u32 pos1 = 0;
    {
      u32 sp = 0;
      stk[sp++] = N;
      u32 c = 0;
      while (sp) {
        u32 u = stk[--sp];
        if (u <= n) {
          if (u == 1) pos1 = c;
          leafOf[c] = u;
          dPos[c] = dist_[u];
          Rr[u] = c;
          c++;
        } else {
          stk[sp++] = ch2[u]; stk[sp++] = ch1[u];
        }
      }
    }
    for (u32 u = n + 1; u <= N; u++) {
      Rr[u] = Rr[ch2[u]];
      A0[Rr[ch1[u]]] = alt_[u];
    }
    // zeroAlt[pos] = altitude of LCA(leaf at pos, leaf of vertex 1); +inf if pos == pos1
    {
      /* The ranges below cover EVERY position except pos1, whose only vertex is v=1 (leafOf[pos1]==1).
         So one store seeds it and no full-array init pass is needed.  posOf[leafOf[i]] == i, so the
         packed word is built with no extra load and no read-modify-write. */
      vinfo[1] = (0xFFFFFFFFull << 32) | (u64)pos1;
      u32 u = N; u32 lo = 0;
      while (u > n) {
        u32 c1 = ch1[u], c2 = ch2[u];
        u32 mid = Rr[c1];                 /* last leaf of c1; c2's leaves start at mid+1 */
        if (pos1 <= mid) {
          u32 hi = Rr[c2];
          for (u32 i = mid + 1; i <= hi; i++) { u32 v = leafOf[i]; vinfo[v] = ((u64)alt_[u] << 32) | (u64)i; }
          u = c1;
        } else {
          for (u32 i = lo; i <= mid; i++) { u32 v = leafOf[i]; vinfo[v] = ((u64)alt_[u] << 32) | (u64)i; }
          lo = mid + 1; u = c2;
        }
      }
    }
    PH_MARK(4);

    // ---- block minima ----
    nn = n; MB = n - 1;
    nb1 = (MB + MSK1) >> SH1;
    nb2 = (nb1 + MSK1) >> SH1;
    {
      for (u32 j = 0; j < nb1; j++) {
        u32 lo = j << SH1, hi = lo + MSK1; if (hi >= nn) hi = nn - 1;
        u32 m1 = 0xFFFFFFFFu, m2 = 0xFFFFFFFFu;
        for (u32 i = lo; i <= hi; i++) { u32 d = dPos[i]; if (d < m1) m1 = d; preD[i] = m1; }
        for (u32 i = hi + 1; i > lo; ) { i--; u32 d = dPos[i]; if (d < m2) m2 = d; sufD[i] = m2; }
      }
      for (u32 j = 0; j < nb1; j++) {
        u32 lo = j << SH1, hi = lo + MSK1;
        u32 hiA = hi; if (hiA >= MB) hiA = MB - 1;
        L1A[j] = scanMin(A0, (int)lo, (int)hiA);
        u32 loD = lo; if (loD >= n) loD = n - 1;
        u32 hiD = hi; if (hiD >= n) hiD = n - 1;
        L1D[j] = scanMin(dPos, (int)loD, (int)hiD);
      }
      for (u32 j = 0; j < nb2; j++) {
        u32 lo = j << SH1, hi = lo + MSK1;
        if (hi >= nb1) hi = nb1 - 1;
        L2A[j] = scanMin(L1A, (int)lo, (int)hi);
        L2D[j] = scanMin(L1D, (int)lo, (int)hi);
      }
      for (u32 i = 0; i < nb1; i++) st1[0][i] = L1D[i];
      for (int k = 1; k < STK; k++) {
        u32 half = 1u << (k - 1);
        for (u32 i = 0; i < nb1; i++) {
          u32 a2 = st1[k - 1][i];
          u32 j2 = i + half;
          u32 b2 = (j2 < nb1) ? st1[k - 1][j2] : 0xFFFFFFFFu;
          st1[k][i] = a2 < b2 ? a2 : b2;
        }
      }
    }
    PH_MARK(5);

    g_Mn = (u64)(~0ull / (u64)n) + 1; g_Ms = (u64)(~0ull / ((u64)S + 1)) + 1;
    // ---- queries ----
    i64 lastans = 0;
    if (K == 1) {
      u32 v=0,p=0;if(Q){v=ni();p=ni();}
      for(u32 qi=0;qi+1u<Q;qi++){
        u32 nv0=ni(),np0=ni();u64 vi=vinfo[v];u32 x=(u32)vi,ans;
        _mm_prefetch((const char*)(A0+(x&~15u)),_MM_HINT_T0);
        _mm_prefetch((const char*)(vinfo+nv0),_MM_HINT_T0);
        if((u32)(vi>>32)>p){ans=0;v=nv0;p=np0;}
        else{
          _mm_prefetch((const char*)(dPos+(x&~15u)),_MM_HINT_T0);
          ans=compMin(x,p,MB,n);
          v=(u32)fastmod((u64)(nv0-1)+ans,(u64)n,g_Mn)+1;
          p=(u32)fastmod((u64)np0+ans,(u64)S+1,g_Ms);
          _mm_prefetch((const char*)(vinfo+v),_MM_HINT_T0);
        }
        pu32(ans);*op_++='\n';
      }
      if(Q){u64 vi=vinfo[v];u32 x=(u32)vi,ans;
        _mm_prefetch((const char*)(A0+(x&~15u)),_MM_HINT_T0);
        if((u32)(vi>>32)>p)ans=0;
        else{_mm_prefetch((const char*)(dPos+(x&~15u)),_MM_HINT_T0);ans=compMin(x,p,MB,n);}
        pu32(ans);*op_++='\n';
      }
    } else {
      for (u32 qi = 0; qi < Q; qi++) {
      u32 v0 = ni(), p0 = ni();
      u64 la = (u64)lastans;
      u32 v, p;
      // [o18y_] K==0 直通:题面保证 1<=v0<=n、0<=p0<=S ⇒ 两个模都是恒等变换,整段删掉
      if (K == 0 && v0 <= n && p0 <= S) { v = v0; p = p0; }
      else {
        v = (u32)fastmod((u64)(v0 - 1) + (u64)K * la, (u64)n, g_Mn) + 1;
        p = (u32)fastmod((u64)p0 + (u64)K * la, (u64)S + 1, g_Ms);
      }
      u64 vi = vinfo[v];
            u32 x = (u32)vi;
      u32 ans;
      /* [n18az-2][pf-hoist] issue the re-aimed level-0 A0 prefetch BEFORE the answer-0 branch:
         the address needs only the low 32 bits of the vinfo load, so the branch, the call and the
         probe setup all become prefetch lead time.  Costs one extra prefetch issued for the 54.2%
         zero-answer queries (measured: 650,882 of 1,200,000).  Arm 2 of the reserve pair; arm 1
         (work/n18az_1.cpp) keeps the prefetch inside the branch.  NOTE: the pre-existing hoist
         experiment #109632 (same hoist, OLD block-base target) measured NEUTRAL (+0.012 ms). */
      _mm_prefetch((const char *)(A0 + (x & ~15u)), _MM_HINT_T0);
      if ((u32)(vi >> 32) > p) {
        ans = 0;
      } else {
        /* [n18az-1][pf-line] (moved above the branch by [n18az-2][pf-hoist]) */
        ans = compMin(x, p, MB, n);
      }
      lastans = (i64)ans;
      pu32(ans); *op_++ = '\n';
    }
    }
    PH_MARK(6);
  }
}

#ifdef LOCAL_TEST
int main() {
  size_t sn = fread(g_in, 1, sizeof(g_in), stdin);
  ip_ = (const unsigned char *)g_in; ie_ = ip_ + sn;
  op_ = g_out;
  solve();
  fwrite(g_out, 1, (size_t)(op_ - g_out), stdout);
  PH_DUMP();
  return 0;
}
#else
int main() { return 0; }
extern "C" void __libc_start_main(void *mmm, int argc, char **argv) {
  (void)mmm;
  unsigned long *p = (unsigned long *)(argv + argc + 1);
  while (*p) p++;
  p++;
  for (; p[0]; p += 2) if (p[0] == 0x6b637564UL) { D = (DI *)p[1]; break; }
  if (D) {
    ip_ = (const unsigned char *)D->s; ie_ = ip_ + D->sn; op_ = D->o;
    solve();
    D->os = (u64)(op_ - D->o);
  }
  __asm__ volatile("syscall" ::"a"(60), "D"(0) : "rcx", "r11", "memory");
  for (;;);
}
#endif

CompilationN/AN/ACompile OKScore: N/A

Testcase #128.07 us132 KBAcceptedScore: 5

Testcase #250.93 us220 KBAcceptedScore: 5

Testcase #374.62 us224 KBAcceptedScore: 5

Testcase #4102.18 us228 KBAcceptedScore: 5

Testcase #5828.86 us460 KBAcceptedScore: 5

Testcase #6143.116 ms26 MB + 552 KBAcceptedScore: 5

Testcase #7797.33 us436 KBAcceptedScore: 5

Testcase #8788.93 us440 KBAcceptedScore: 5

Testcase #9795.28 us436 KBAcceptedScore: 5

Testcase #10131.207 ms24 MB + 244 KBAcceptedScore: 5

Testcase #11131.674 ms24 MB + 248 KBAcceptedScore: 5

Testcase #12158.657 ms30 MB + 860 KBAcceptedScore: 5

Testcase #13159.171 ms30 MB + 848 KBAcceptedScore: 5

Testcase #14158.654 ms30 MB + 864 KBAcceptedScore: 5

Testcase #151.024 ms504 KBAcceptedScore: 5

Testcase #161.019 ms504 KBAcceptedScore: 5

Testcase #17158.639 ms30 MB + 860 KBAcceptedScore: 5

Testcase #18158.617 ms30 MB + 860 KBAcceptedScore: 5

Testcase #19230.955 ms34 MB + 276 KBAcceptedScore: 5

Testcase #20230.499 ms34 MB + 324 KBAcceptedScore: 5


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