1 条题解

  • 0
    @ 2025-10-20 16:51:49

    问题分析

    本题的核心是计算棋盘上被攻击的格子总数,其中格子被攻击的条件是:所有能攻击到该格子的棋子的武力值异或和大于0。棋子的攻击方式与中国象棋的“车”相同,即能攻击同一行和同一列的所有格子。

    关键观察:对于格子 (x,y)(x, y),能攻击到它的棋子是第 xx 行的所有棋子和第 yy 列的所有棋子。设第 xx 行所有棋子的武力值异或和为 rxor[x]rxor[x],第 yy 列所有棋子的武力值异或和为 cxor[y]cxor[y],则该格子的总攻击异或和为 rxor[x]cxor[y]rxor[x] \oplus cxor[y]。因此,格子 (x,y)(x, y) 被攻击的条件等价于 rxor[x]cxor[y]0rxor[x] \oplus cxor[y] \neq 0(即 rxor[x]cxor[y]rxor[x] \neq cxor[y])。

    核心思路

    1. 总数转换:总格子数为 n2n^2,被攻击的格子数 = 总格子数 - 不被攻击的格子数(即 rxor[x]=cxor[y]rxor[x] = cxor[y] 的格子数)。
    2. 计数维护:用 rcnt[v]rcnt[v] 表示异或和为 vv 的行数,ccnt[v]ccnt[v] 表示异或和为 vv 的列数。则不被攻击的格子数为 (rcnt[v]×ccnt[v])\sum (rcnt[v] \times ccnt[v])(对所有可能的 vv 求和)。
    3. 动态更新:每次移动棋子时,需更新棋子原位置和新位置的行、列异或和(rxorrxorcxorcxor),并同步调整 rcntrcntccntccnt 的计数,进而更新不被攻击的格子数,最终得到被攻击的格子数。

    算法流程

    1. 初始化:初始时无棋子,所有行和列的异或和均为0,因此 rcnt[0]=nrcnt[0] = nccnt[0]=nccnt[0] = n,初始不被攻击的格子数为 n×nn \times n
    2. 添加/移除棋子
      • 移除棋子时,对原行 rr 和原列 cc,将其异或和更新(异或棋子的武力值),并调整 rcntrcntccntccnt 中对应值的计数。
      • 添加棋子时,对新行 rr 和新列 cc,执行与移除类似的操作(异或运算具有可逆性,添加等价于再次异或该武力值)。
    3. 计算答案:每次操作后,被攻击的格子数为 n2(rcnt[v]×ccnt[v])n^2 - \sum (rcnt[v] \times ccnt[v])

    算法标签

    哈希表 异或运算 动态维护 计数统计

    • 1

    信息

    ID
    3591
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者