@description@

有一个长度为N的数组,甲乙两人在上面进行这样一个游戏:

首先,数组上有一些格子是白的,有一些是黑的。然后两人轮流进行操作。每次操作选择一个白色的格子,假设它的下标为x。接着,选择一个大小在1~n/x之间的整数k,然后将下标为x、2x、...、kx的格子都进行颜色翻转。不能操作的人输。

现在甲(先手)有一些询问。每次他会给你一个数组的初始状态,你要求出对于这种初始状态他是否有必胜策略。

原题传送门。

@solution@

考虑一个巧妙(至少我觉得很巧妙)的转化:我们把白色格子看作初始有一个棋子,颜色翻转变成直接在格子上放棋子。

当一个格子有多于 1 个棋子存在时,先手对该格子操作,后手可以模仿相同的操作。因此并不影响。

这样子转化的好处是:我们把每个白格子独立出来,变成互不干涉的组合游戏。因此就可以使用 sg 函数来刻画了。

可以列出转移 \(sg(x) = mex(0, sg(2x), sg(2x)\oplus sg(3x), \dots)\)。

然而 n 很大,考虑怎么优化。

注意当 x > n/2 时 sg(x) 相同,继续算发现 n/2 >= x > n/3 时 sg(x) 也相同,因此不难猜测到 \(sg(x) = f(\lfloor\frac{n}{x}\rfloor)\)。证明根据 sg 的转移式易证。

由 \(sg(x) = mex(0, sg(2x), sg(2x)\oplus sg(3x), \dots)\) 可得 f 的转移:

\[f(\lfloor\frac{n}{x}\rfloor) = mex(0, f(\lfloor\frac{n}{2x}\rfloor), f(\lfloor\frac{n}{2x}\rfloor)\oplus f(\lfloor\frac{n}{3x}\rfloor), \dots)\\
f(p) = mex(0, f(\lfloor\frac{p}{2}\rfloor), f(\lfloor\frac{p}{2}\rfloor)\oplus f(\lfloor\frac{p}{3}\rfloor), \dots)
\]

分块转移即可。存储 f 用类似杜教筛的方法即可。

时间复杂度 \(\sum_{i=1}^{\sqrt{n}}(\sqrt{\frac{n}{i}} + \sqrt{i})\)。积分拟合一下大概是 \(O(n^{\frac{3}{4}})\)。

@accepted code@

  1. #include <cmath>
  2. #include <cstdio>
  3. #include <algorithm>
  4. using namespace std;
  5. const int SQRT = 32000;
  6. int N; int sg1[SQRT + 5], sg2[SQRT + 5];
  7. int *sg(int x) {return x > SQRT ? sg1 + (N/x) : sg2 + x;}
  8. int a[2*SQRT + 5], vis[2*SQRT + 5], cnt;
  9. void get() {
  10. for(int i=1;i<=N;i=(N/(N/i))+1) a[++cnt] = N/i;
  11. for(int i=cnt;i>=1;i--) {
  12. int tmp = 0;
  13. for(int j=2;j<=a[i];) {
  14. int p = a[i] / j, k = a[i] / p, x = (*sg(p)) ^ tmp;
  15. vis[x] = i;
  16. if( (k - j + 1) & 1 )
  17. tmp = x;
  18. j = k + 1;
  19. }
  20. int ans = 1;
  21. while( vis[ans] == i ) ans++;
  22. (*sg(a[i])) = ans;
  23. }
  24. }
  25. int main() {
  26. scanf("%d", &N), get();
  27. int K; scanf("%d", &K);
  28. for(int i=1;i<=K;i++) {
  29. int W, ans = 0; scanf("%d", &W);
  30. for(int j=1;j<=W;j++) {
  31. int x; scanf("%d", &x);
  32. ans ^= (*sg(N/x));
  33. }
  34. puts(ans ? "Yes" : "No");
  35. }
  36. }

@details@

能少用除法就少用除法,毕竟最慢运算符(好像不是,取模是最慢的),很可能(像我一样)被卡常。

@bzoj - 4035@ [HAOI2015]数组游戏的更多相关文章

  1. 【BZOJ 4035】 4035: [HAOI2015]数组游戏 (博弈)

    4035: [HAOI2015]数组游戏 Time Limit: 15 Sec  Memory Limit: 32 MBSubmit: 181  Solved: 89 Description 有一个长 ...

  2. bzoj4035 [HAOI2015]数组游戏

    这题显然把每个白格子看成一个子游戏 一个白格子$x$的$sg$值是$mex{[0,sg[2x],sg[2x] XOR sg[3x].....]}$ 打表发现一个数的$sg$值只和$n/x$有关,然后分 ...

  3. [HAOI2015]数组游戏

    题目大意: 有一排n个格子,每个格子上都有一个白子或黑子,在上面进行游戏,规则如下: 选择一个含白子的格子x,并选择一个数k,翻转x,2x,...,kx格子上的子. 不能操作者负. 思路: 将“某个格 ...

  4. 【BZOJ4035】数组游戏(博弈论)

    [BZOJ4035]数组游戏(博弈论) 题面 BZOJ 洛谷 题解 很明显是一个翻硬币游戏的变形,因此当前局面的\(SG\)函数值就是所有白格子单独存在的\(SG\)函数的异或和. 那么,对于每一个位 ...

  5. bzoj 3991: [SDOI2015]寻宝游戏 虚树 set

    目录 题目链接 题解 代码 题目链接 bzoj 3991: [SDOI2015]寻宝游戏 题解 发现每次答案就是把虚树上的路径*2 接在同一关键点上的点的dfs序是相邻的 那么用set动态维护dfs序 ...

  6. bzoj 3232: 圈地游戏

    bzoj 3232: 圈地游戏 01分数规划,就是你要最大化\(\frac{\sum A}{\sum B}\),就二分这个值,\(\frac{\sum A}{\sum B} \geq mid\) \( ...

  7. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  8. [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)

    [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...

  9. BZOJ 4033: [HAOI2015]树上染色题解

    BZOJ 4033: [HAOI2015]树上染色题解(树形dp) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327400 原题地址: BZOJ 403 ...

随机推荐

  1. mybatis的多表联查

    多对一连表查询简单记录

  2. Magicodes.IE 2.2发布

    Magicodes.IE 导入导出通用库,支持Dto导入导出以及动态导出,支持Excel.Word.Pdf.Csv和Html.已加入NCC开源组织. Magicodes.IE 2.0发布 Magico ...

  3. JAVA POI替换EXCEL模板中自定义标签(XLSX版本)满足替换多个SHEET中自定义标签

    个人说明:为了简单实现导出数据较少的EXCEL(根据自定义书签模板) 一.替换Excel表格标签方法```/** * 替换Excel模板文件内容 * @param map * 需要替换的标签建筑队形式 ...

  4. pytest跟unittest的优势跟劣势

    一.用例编写规则 1.使用unittest编写测试用例必须遵循以下规则: 1.必须首先 导入 import unittest 2.测试类必须要继承 unittest.TestCase 3.测试方法必须 ...

  5. S32DS编译程序出现Type region `SRAM' overflowed by 19240 bytes错误

    用S32DS编译工程遇到Type region `SRAM' overflowed by 19240 bytes错误(芯片为S9KEAZ64AMLH) 程序中未初始化的变量存放SRAM中 当程序出现未 ...

  6. NodeJS——模块全局安装路径配置以及关于supervisor的问题解释

    下载安装NodeJS后,在自己选择的路径下会有如下的文件: 默认情况下NodeJS安装会同时安装npm(模块管理器:用于管理用户require的模块,有全局和本地两种). 注:全局:执行npm  in ...

  7. 自定义值类型一定不要忘了重写Equals,否则性能和空间双双堪忧

    一:背景 1. 讲故事 曾今在项目中发现有同事自定义结构体的时候,居然没有重写Equals方法,比如下面这段代码: static void Main(string[] args) { var list ...

  8. Rocket - tilelink - RegionReplicator

    https://mp.weixin.qq.com/s/XZVCdt50tM6lavchGm9GRg   简单介绍RegionReplicator的实现.   ​​   1. 基本介绍   根据mask ...

  9. cmd 启动mysql,发生系统错误5

    在运行cmd的时候,使用管理员身份运行.

  10. eclipse 界面复原

    Windows-----Perspective-----Reset perspective