题目大意:
  有一排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. CodeForces 1011B

    Description Natasha is planning an expedition to Mars for nn people. One of the important tasks is t ...

  2. 【leetcode 简单】第三十二题 买卖股票的最佳时机Ⅱ

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你必须在再次 ...

  3. sublime出现卡顿的现象

    这几天,用sublime总是写一个代码就卡顿,卡卡卡,,,,要死的~ 最后,才发现是因为安装了一个插件:GitGutter插件,所以,小伙伴们请跟上我的节奏~~~~~ (1)Ctrl + Shift ...

  4. 爬虫实战--使用Selenium模拟浏览器抓取淘宝商品美食信息

    from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exce ...

  5. Dull Chocolates Gym - 101991D 离散化 前缀和

    题目链接:https://vjudge.net/problem/Gym-101991D 具体思路:首先看数据范围,暴力肯定不可以,可以下离散化,然后先求出离散化后每一个点到(1,1)的符合题目的要求的 ...

  6. Mutex, semaphore, spinlock的深度解析

    Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个.一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行. Semaphor ...

  7. 在新版linux上编译老版本的kernel出现kernel/timeconst.h] Error 255

    在使用ubuntu16.4编译Linux-2.6.31内核时出现这样的错误 可以修改timeconst.pl的内容后正常编译. 以下是编译错误提示的内容: Can't use 'defined(@ar ...

  8. 64_s2

    sipwitch-1.9.15-3.fc26.x86_64.rpm 13-Feb-2017 09:19 162822 sipwitch-cgi-1.9.15-3.fc26.x86_64.rpm 13- ...

  9. [MySQL] gap lock/next-key lock浅析

    当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将锁细分为如下几种子类型: record lock (RK) 记录锁, 仅仅锁住索引记录的一行 ...

  10. 「caffe编译bug」 undefined reference to `boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::__cxx11

    CXX/LD -o .build_release/tools/test_net.binCXX/LD -o .build_release/tools/convert_annoset.binCXX/LD ...