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

思路:
  将“某个格子上有一个白子 ”视作游戏的一个状态。
  对于状态x,sg(x)=mex{sg(2x),sg(2x)^sg(3x),sg(2x)^sg(3x)^...^sg(kx)}。
  由于SG函数的取值只与棋盘大小和棋子位置有关,因此我们可以记忆化。
  然后我们就有了暴力构造SG函数的程序,实测只能过40%的点,大力卡常以后勉强能50%。
  而且空间显然也开不下,只能用hash_map。
  然而这题的SG函数有一些神奇的性质,例如,对于大小为10的棋盘,当x分别为1~10时,sg(x)分别为:
  4 1 2 2 2 1 1 1 1 1
  我们将它们进行分组:
  (4)(1)(2)(2 2)(1 1 1 1 1)
  可以发现,当不同棋子可以往后跳的步数相同时,它们的SG函数相同。
  显然可以把它们分为2sqrt(n)组。
  其中前sqrt(n)组都是一个子一组,后sqrt(n)组都是很多个一组。
  这样,以sqrt(n)为界,对于我们需要的函数,判断一下参数的范围即可。

 #include<cmath>
#include<cstdio>
#include<cctype>
inline int getint() {
char ch;
while(!isdigit(ch=getchar()));
int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=;
int sg[N][],mex[N];
int n,block;
inline int next(const int &x,const int &y) {
return x==y?x+:y/(y/(x+));
}
void getsg() {
for(register int i=;i<=n;i=next(i,n)) {
for(register int k=,tmp=;k<=i;k=next(k,i)) {
int x=i/k;
int t=(x>block)?sg[n/x][]:sg[x][];
mex[tmp^t]=i;
if((i/x-i/(x+))&) tmp^=t;
}
int tmp=;
while(mex[tmp]==i) tmp++;
((i>block)?sg[n/i][]:sg[i][])=tmp;
}
}
int main() {
n=getint();
block=floor(sqrt(n));
getsg();
for(register int m=getint();m;m--) {
int ans=;
for(register int w=getint();w;w--) {
const int x=getint();
ans^=(n/x>block)?sg[n/(n/x)][]:sg[n/x][];
}
puts(ans?"Yes":"No");
}
return ;
}

暴力构造SG函数的程序:

 #include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<ext/hash_map>
inline int getint() {
char ch;
while(!isdigit(ch=getchar()));
int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
__gnu_cxx::hash_map<int,int> sg,mex;
int n;
int getsg(const int x) {
if(sg.count(x)) return sg[x];
for(int k=,tmp=;k<=n/x;k++) {
tmp^=getsg(x*k);
mex[tmp]=x;
}
for(sg[x]=;mex[sg[x]]==x;sg[x]++);
return sg[x];
}
int main() {
n=getint();
for(int i=n;i;i--) getsg(i);
for(int m=getint();m;m--) {
int ans=;
for(int w=getint();w;w--) {
ans^=getsg(getint());
}
puts(ans?"Yes":"No");
}
return ;
}

[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. @bzoj - 4035@ [HAOI2015]数组游戏

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一个长度为N的数组,甲乙两人在上面进行这样一个游戏: 首先,数 ...

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

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

  5. bzoj4035【HAOI2015】数组游戏

    题目描述 有一个长度为N的数组,甲乙两人在上面进行这样一个游戏:首先,数组上有一些格子是白的,有一些是黑的.然 后两人轮流进行操作.每次操作选择一个白色的格子,假设它的下标为x.接着,选择一个大小在1 ...

  6. 【LOJ】#2126. 「HAOI2015」数组游戏

    题解 简单分析一下就知道\(\lfloor \frac{N}{i} \rfloor\)相同的\(i\)的\(sg\)函数相同 所以我们只要算\(\sqrt{n}\)个\(sg\)函数就好 算每一个\( ...

  7. sg函数小结

    sg函数小结 sg函数是处理博弈问题的重要工具. 我们知道sg(x)=mex{sg(j)|x能到达状态j} sg(x)=0时代表后手赢,否则先手赢. 对于一个问题,如果某些子问题是相互独立的,我们就可 ...

  8. 最浅谈的SG函数

    [更新] Nim游戏的经验: 每次最多取m个——%(m+1) 阶梯nim——奇数位无视,看偶数位互相独立,成一堆一堆的石子 . . . . 既然被征召去汇总算法..那么挑个简单点的SG函数好了.. 介 ...

  9. HAOI2015 简要题解

    「HAOI2015」树上染色 题意 有一棵点数为 \(N\) 的树,树边有边权.给你一个在 \(0 \sim N\) 之内的正整数 \(K\),你要在这棵树中选择 \(K\) 个点,将其染成黑色,并将 ...

随机推荐

  1. webpack编译报错:Module not found: Error: Cannot resolve 'file' or 'directory' ./../../node_modules..

    在同事的mac电脑上,可以正常编译,拿到我这边就出错了(⊙﹏⊙) 好像是webpack在window下的一个bug,需要让 webpack 和你的项目保持在一个盘符下,参考. 解决方法: 修改conf ...

  2. php上传文件大小限制的方法详解

    打开php.ini,首先找到file_uploads = on ;是否允许通过HTTP上传文件的开关.默认为ON即是开upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就 ...

  3. 设计模式之Proxy

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 为什么要使用Proxy? 1.授权机制 不同级别的用户对同一对象拥有不同的访问权利. 2.某个客户端不 ...

  4. CRF++模板使用(转)

    CRF++模板构建分为两类,一类是Unigram标注,一类是Bigram标注. Unigram和Bigram模板分别生成CRF的状态特征函数  和转移特征函数  .其中  是标签,  是观测序列,   ...

  5. 关于linux环境下crontab命令环境变量的问题

    这几天在弄数据库备份的事情,其中涉及到使用crontab命令自动执行shell脚本的问题,发现将写好的数据库导出脚本export.sh ################################ ...

  6. 集合框架之Map学习

    Map接口的实现类有HashTable.HashMap.TreeMap等,文章学习整理了“ Map和HashMap的使用方法”. /** * Map和HashMap的使用方法 */public sta ...

  7. 使用xbee连接地面站和飞控

    Zigbee是一种短距离.低功耗的近距离无线组网通讯技术,主要适用于自动控制和远程控制领域,可以嵌入各种设备. DIGI的ZigBee产品XBee小型但却是一个功能完善的ZigBee收发器(即接收器/ ...

  8. Ubuntu每次开机后提示:检测到系统程序出现问题的解决方法

    首先,错误报告存放位置: cd /var/crash/ ls //可以查看错误报告 1 2 sudo rm /var/crash/* //删除该目录下的所有文件 1 但是,这只是删除掉的是错误报告,如 ...

  9. python使用virtualenv

    virtualenv是python的虚拟环境,可以同时存在多个不同的虚拟环境. #1.安装virtualenv pip install virtualenv #2.创建目录 mkdir myproje ...

  10. ASP.NET Core 2.0 MVC 发布部署--------- IIS 具体操作

    .Net Core 部署到 IIS系统中的步骤 一.IIS 配置 启用 Web 服务器 (IIS) 角色并建立角色服务. 1.Windows Ddesktop 桌面操作系统(win7及更高版本) 导航 ...