[HAOI2015]数组游戏
题目大意:
有一排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]数组游戏的更多相关文章
- 【BZOJ 4035】 4035: [HAOI2015]数组游戏 (博弈)
4035: [HAOI2015]数组游戏 Time Limit: 15 Sec Memory Limit: 32 MBSubmit: 181 Solved: 89 Description 有一个长 ...
- bzoj4035 [HAOI2015]数组游戏
这题显然把每个白格子看成一个子游戏 一个白格子$x$的$sg$值是$mex{[0,sg[2x],sg[2x] XOR sg[3x].....]}$ 打表发现一个数的$sg$值只和$n/x$有关,然后分 ...
- @bzoj - 4035@ [HAOI2015]数组游戏
目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一个长度为N的数组,甲乙两人在上面进行这样一个游戏: 首先,数 ...
- 【BZOJ4035】数组游戏(博弈论)
[BZOJ4035]数组游戏(博弈论) 题面 BZOJ 洛谷 题解 很明显是一个翻硬币游戏的变形,因此当前局面的\(SG\)函数值就是所有白格子单独存在的\(SG\)函数的异或和. 那么,对于每一个位 ...
- bzoj4035【HAOI2015】数组游戏
题目描述 有一个长度为N的数组,甲乙两人在上面进行这样一个游戏:首先,数组上有一些格子是白的,有一些是黑的.然 后两人轮流进行操作.每次操作选择一个白色的格子,假设它的下标为x.接着,选择一个大小在1 ...
- 【LOJ】#2126. 「HAOI2015」数组游戏
题解 简单分析一下就知道\(\lfloor \frac{N}{i} \rfloor\)相同的\(i\)的\(sg\)函数相同 所以我们只要算\(\sqrt{n}\)个\(sg\)函数就好 算每一个\( ...
- sg函数小结
sg函数小结 sg函数是处理博弈问题的重要工具. 我们知道sg(x)=mex{sg(j)|x能到达状态j} sg(x)=0时代表后手赢,否则先手赢. 对于一个问题,如果某些子问题是相互独立的,我们就可 ...
- 最浅谈的SG函数
[更新] Nim游戏的经验: 每次最多取m个——%(m+1) 阶梯nim——奇数位无视,看偶数位互相独立,成一堆一堆的石子 . . . . 既然被征召去汇总算法..那么挑个简单点的SG函数好了.. 介 ...
- HAOI2015 简要题解
「HAOI2015」树上染色 题意 有一棵点数为 \(N\) 的树,树边有边权.给你一个在 \(0 \sim N\) 之内的正整数 \(K\),你要在这棵树中选择 \(K\) 个点,将其染成黑色,并将 ...
随机推荐
- webpack编译报错:Module not found: Error: Cannot resolve 'file' or 'directory' ./../../node_modules..
在同事的mac电脑上,可以正常编译,拿到我这边就出错了(⊙﹏⊙) 好像是webpack在window下的一个bug,需要让 webpack 和你的项目保持在一个盘符下,参考. 解决方法: 修改conf ...
- php上传文件大小限制的方法详解
打开php.ini,首先找到file_uploads = on ;是否允许通过HTTP上传文件的开关.默认为ON即是开upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就 ...
- 设计模式之Proxy
设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 为什么要使用Proxy? 1.授权机制 不同级别的用户对同一对象拥有不同的访问权利. 2.某个客户端不 ...
- CRF++模板使用(转)
CRF++模板构建分为两类,一类是Unigram标注,一类是Bigram标注. Unigram和Bigram模板分别生成CRF的状态特征函数 和转移特征函数 .其中 是标签, 是观测序列, ...
- 关于linux环境下crontab命令环境变量的问题
这几天在弄数据库备份的事情,其中涉及到使用crontab命令自动执行shell脚本的问题,发现将写好的数据库导出脚本export.sh ################################ ...
- 集合框架之Map学习
Map接口的实现类有HashTable.HashMap.TreeMap等,文章学习整理了“ Map和HashMap的使用方法”. /** * Map和HashMap的使用方法 */public sta ...
- 使用xbee连接地面站和飞控
Zigbee是一种短距离.低功耗的近距离无线组网通讯技术,主要适用于自动控制和远程控制领域,可以嵌入各种设备. DIGI的ZigBee产品XBee小型但却是一个功能完善的ZigBee收发器(即接收器/ ...
- Ubuntu每次开机后提示:检测到系统程序出现问题的解决方法
首先,错误报告存放位置: cd /var/crash/ ls //可以查看错误报告 1 2 sudo rm /var/crash/* //删除该目录下的所有文件 1 但是,这只是删除掉的是错误报告,如 ...
- python使用virtualenv
virtualenv是python的虚拟环境,可以同时存在多个不同的虚拟环境. #1.安装virtualenv pip install virtualenv #2.创建目录 mkdir myproje ...
- ASP.NET Core 2.0 MVC 发布部署--------- IIS 具体操作
.Net Core 部署到 IIS系统中的步骤 一.IIS 配置 启用 Web 服务器 (IIS) 角色并建立角色服务. 1.Windows Ddesktop 桌面操作系统(win7及更高版本) 导航 ...