当前位置: 首页 > news >正文

异或高斯消元

题干概述

在一片古老遗迹的深处,两位旅人发现了一排排风化的石块,相邻的石块之间用生锈的金属环连接。每一排都形成一条,而墙上模糊的刻文将这种游戏称为「链上 Nim」。

一条长度为 LL 的链包含 LL 个顶点和 L−1L−1 条连边。玩家 11 先手,之后两位玩家轮流行动。在每一回合,当前玩家选择一条链,并按照固定的游戏规则在其中进行一次合法操作。这是一个公平组合游戏:可以选择的操作只取决于当前局面,而与轮到了哪位玩家无关。无法继续行动的玩家判负。

可惜,刻文中记载具体操作规则的部分已经损坏。两位旅人只知道,根据 Sprague--Grundy 定理,每条链仍然有唯一的非负整数SG 值。对于每个可能的链长 LL,记一条该长度链的 SG 值为 GLGL​。

一场游戏可以在若干条非空、彼此独立的链上同时进行。每次行动只会影响玩家选中的那一条链。因此,若一个局面中各条链的长度为 L1,L2,…,LCL1​,L2​,…,LC​,那么整个局面的 SG 值等于各条链 SG 值的Nim 和,也就是按位异或和:

GL1xorGL2xor⋯xorGLC.GL1​​xorGL2​​xor⋯xorGLC​​.

一位新人曾经旁观了 KK 个历史局面。对于每场过去的游戏,他记下了局面中所有链的长度,并向熟悉游戏的玩家询问了整个局面的 SG 值。然而,他并不知道每个 GLGL​ 分别是多少。

现在,他又遇到了 QQ 个新局面,并想知道:

「只使用笔记中的历史记录,能否唯一确定这个局面的 SG 值?」

如果根据历史记录能够唯一确定这个局面的 SG 值,就输出这个值;如果无法确定,就输出 −1−1。

Input

第一行包含一个整数 TT(1≤T≤101≤T≤10),表示测试用例的数量。

接下来依次描述 TT 组测试用例。对于每组测试用例:

第一行包含一个整数 KK(1≤K≤1001≤K≤100),表示历史局面数量。

接下来的 KK 个历史局面均恰好用两行描述:

  • 第一行包含两个整数 CC 和 SS(1≤C≤1001≤C≤100,0≤S≤1040≤S≤104),分别表示链的数量和该局面的已知 SG 值。
  • 第二行恰好包含 CC 个整数 L1,L2,…,LCL1​,L2​,…,LC​(1≤Li≤1001≤Li​≤100),表示以顶点数计算的各条链的长度。

接下来一行包含一个整数 QQ(1≤Q≤1001≤Q≤100),表示询问数量。

接下来的 QQ 个询问均恰好用两行描述:

  • 第一行包含一个整数 DD(1≤D≤1001≤D≤100),表示链的数量。
  • 第二行恰好包含 DD 个整数 R1,R2,…,RDR1​,R2​,…,RD​(1≤Ri≤1001≤Ri​≤100),表示以顶点数计算的各条链的长度。

链长可以以任意顺序给出,也可以重复。所有被描述的局面都不为空。

Output

对于每组测试用例中的每个询问,输出一行一个整数。

Sample Input

1 2 2 5 1 2 2 6 2 3 5 2 1 2 2 1 3 1 1 2 4 4 1 4

Sample Output

5 3 -1 0 -1

对于这个题,可以理解为,在可能有1-100个未知量,我给出若干个异或线性方程组,最后给出一个查询方程,看这个方程能不能由之前的方程组给出,那么和高斯消元(线性代数解有唯一解的方程组)类似,我们可以把每个方程当作一个基向量,每次保留未出现过的当前方程位最高的未知量,对于异或方程,我们计算基向量要减去当前向量,(__int128)mask^=r[i]即可,对应的sg值相当于增广矩阵的右值,s^=sg[i],找到第一个非0位更新返回,之后查询即可(100位要从1-100,不是0-99),简要代码如下:

#include <bits/stdc++.h> using namespace std; __int128 ini = 0; long long had[101], sg[101]; __int128 r[101]; void insert(__int128 mask, int s) { for (int i = 100; i >= 0; i--) { if (!((mask >> i & 1))) continue; if (!had[i]) { had[i] = true; r[i] = mask; sg[i] = s; return; } mask ^= r[i]; // 基向量相消 s ^= sg[i]; } } long long query(__int128 mask, long long s) { for (int i = 100; i >= 0; i--) { if (!(mask >> i & 1)) continue; if (!had[i]) return -1; mask ^= r[i]; // 消去当前 s ^= sg[i]; } return s; } int main() { int t; cin >> t; while (t--) { memset(had, 0, sizeof(had)); memset(sg, 0, sizeof(sg)); memset(r, 0, sizeof(r)); int n; cin >> n; while (n--) { int c, s; cin >> c >> s; __int128 mask = 0; while (c--) { int l; cin >> l; mask ^= ((__int128)1 << l); } insert(mask, s); } int q; cin >> q; while (q--) { __int128 mask = 0; int len; cin >> len; while (len--) { int ri; cin >> ri; mask ^= (__int128)1 << ri; } cout << query(mask, 0) << "\n"; } } }
http://www.jsqmd.com/news/1339553/

相关文章:

  • 解析制造业三维动画:源文件和模型版权归属及交付权限科普
  • BIOS/UEFI重置全攻略:从原理到实操,解决电脑启动与硬件故障
  • Windows U盘安全弹出失败全攻略:从原理到排查的完整解决方案
  • 2026GEO收录效果检测工具哪家好?避坑指引及优选推荐
  • 沉浸式消防报警训练系统设计与应用
  • 百度网盘直链解析工具的原理与高效下载实践
  • 智能制造行业客户体验管理系统推荐:基于客户旅程地图(CJM)的智能硬件全旅程体验数据采集与触发引擎设计
  • LinkSwift网盘直链下载助手:一个脚本解决九大网盘下载难题
  • Fantia内容下载工具完整指南:如何高效备份创作者作品
  • 福来婴童线有哪些产品?0-3岁待产包做功课的爸妈,这份清单直接收 - 甄选测评馆
  • 多个 Skill 组合在一起就是 Agent 吗?
  • 终极GitHub加速指南:3分钟安装,10倍下载速度提升!
  • 终极指南:KMS智能激活工具一键解决Windows和Office激活难题
  • 掌握Windows窗口置顶:3步消除多任务切换烦恼
  • 设备预测性维护失效真相大起底,92%企业忽略的3层数据断点与工业大模型校准方法
  • 国产数据库KingbaseES替代Oracle的实践与优化
  • 英雄联盟智能助手Seraphine:3分钟免费安装,实时战绩查询与BP决策优化全攻略
  • 2026GEO获客效果评估工具哪家好?避坑指引及优选推荐
  • GESP跨级报考新规解读:从Scratch到C++的加速路径与备考策略
  • 3分钟免费实现Figma中文界面:设计师必备的完整汉化指南
  • 2026高端工业密封圈深度测评:重庆迪固极端工况密封全方案解析 - 深度智识库
  • 深入理解Select:I/O多路复用的核心原理与网络编程实践
  • 避坑必看!2026工程建设监管系统怎么选?一文讲清 - 互联网科技品牌测评
  • JavaScript性能优化20个实战技巧与常见误区
  • 阿里云国际站(云老大): DMS 连接报实例不可用?从现象到根因排障全记录
  • Redis缓存进阶:从穿透、雪崩到多级缓存架构的实战解决方案
  • JMeter接口测试中的参数加密实现与优化
  • 魔兽争霸III高效优化必备:5分钟解锁300帧与完美宽屏体验
  • Ubuntu 24.04.3 LTS安装报错排查与解决方案
  • HTTP基础认证原理与BurpSuite爆破实战:从CTF靶场到Python脚本实现