【bzoj3567】江南乐
Solution
今天开始啃博弈论了qwq
先mark一篇很棒的博客Portal -->博弈论学习资料
稍微总结一下两个自己容易混淆的点:
1.有一类博弈论问题的主要步骤是首先将原游戏拆分成若干个独立的子游戏,然后原游戏的\(sg\)就是子游戏\(sg\)值的异或和
2.有向图游戏中,对于一个局面,它的\(sg\)是其后继局面的\(sg\)值的\(mex\)
这题的话,首先想怎么拆分
不难发现每一堆的操作其实是独立的,所以我们可以将对一堆石子进行操作看成这个游戏的子游戏
那么问题就变成了要求一堆石子数量为\(x\)的石子堆的\(sg\)值,我们考虑用这堆石子的数量来描述这个局面,那么也就是说我们现在要求\(sg(x)\)
这其实相当于一个有向图游戏
先不考虑时间和空间问题,我们想如何暴力求解\(sg(x)\),一个可行的方法就是记忆化搜索,对于当前局面\(x\),我们枚举一个\(i\)表示将这\(x\)个石子分成的堆数,那么这个后继局面的\(sg\)值就应该是\(sg(a_1)\wedge sg(a_2)\wedge sg(a_3)\wedge...\wedge sg(a_i)\),其中\(a\)表示的是分成\(i\)堆之后每堆的石子数量,然后\(sg(x)\)应该是所有的后继局面的\(sg\)值的\(mex\)
弄清楚这点之后,我们考虑分成\(i\)堆应该怎么分,根据题目要求,显然我们只能分成\(x\%i\)堆石子数量为\(\lfloor \frac{x}{i}\rfloor+1\)的,和\(i-x\%i\)堆石子数量为\(\lfloor \frac{x}{i}\rfloor\)的,那么根据异或的性质不难得出结论分成\(i\)堆的后继局面的\(sg\)值为:
\]
具体的话就是因为如果是偶数那一部分全部异或起来就是\(0\)了
那么现在我们可以写出来一个暴力,考虑如何优化这个东西
注意到里面有一个\(\lfloor \frac{x}{i}\rfloor\),然后这个东西只有\(\sqrt x\)种取值,处理这种东西我们可以用一个分段的套路(莫比乌斯反演既视感qwq),把所有\(\lfloor \frac{x}{i}\rfloor\)相同的\(i\)一起算,接下来在\(\lfloor \frac{x}{i}\rfloor\)相同的前提下,我们再考虑一下奇偶性的问题:会发现如果说\(i\)的奇偶性不变的话,那么\(x%i\)和\(i-x\%i\)的奇偶性也不会发生变化,又因为\(\lfloor \frac{x}{i}\rfloor\)相同,也就是说\(i\)奇偶性不变的话\(sg\)值也不会发生变化
那么所以,我们只要对于每一段\(\lfloor \frac{x}{i}\rfloor\)相同的\(i\),算一下\(i\)的\(sg\)再算一下\(i+1\)的\(sg\),就能够代表这里所有的情况了,总共是\(2\sqrt x\)个数,记忆化搜索一波,问题不大
最后是一些实现上的小细节,如果说求\(mex\)是暴力求的话,我们不能够在递归的时候每次都将判断的数组重置,所以考虑用一个打标记的方式来判,具体就是每次赋成一个不同的\(mark\)值就好了,但是这里有一个问题就是一旦采取这样的方式,在开始统计之后就不能再进行递归操作,所以我们应该在统计之前先递归一遍把这\(2\sqrt x\)个\(sg\)算出来,要注意因为中间可能会递归到自己,所以一开始要先把\(x\)的\(sg\)值赋成\(0\),防止。。一直递归下去qwq
当然啦如果你写的是递推版本就没有那么多麻烦事了qwq
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100010;
int f[N];
int vis[N];
int n,m,T,F,ans,mark;
int sg(int x){
if (f[x]!=-1) return f[x];
int tmp1,tmp2,tmp=0;
f[x]=0;//stop first
for (int i=2,pos=0;i<=x;i=pos+1){
pos=x/(x/i);
sg(x/i),sg(x/i+1);
}
++mark;
for (int i=2,pos=0;i<=x;i=pos+1){
pos=x/(x/i);
tmp=0;
tmp1=i-x%i;
tmp2=x%i;
if (tmp1&1) tmp^=f[x/i];
if (tmp2&1) tmp^=f[x/i+1];
vis[tmp]=mark;
if (x/(i+1)==x/i){
tmp=0;
tmp1=(i+1)-x%(i+1);
tmp2=x%(i+1);
if (tmp1&1) tmp^=f[x/(i+1)];
if (tmp2&1) tmp^=f[x/(i+1)+1];
vis[tmp]=mark;
}
}
for (int i=0;i<=x;++i)
if (vis[i]!=mark){f[x]=i;return f[x];}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x;
scanf("%d%d",&T,&F);
for (int i=F;i<N;++i) f[i]=-1;
for (int o=1;o<=T;++o){
scanf("%d",&n);
ans=0;
for (int i=1;i<=n;++i){
scanf("%d",&x);
ans^=sg(x);
}
if (ans==0) printf("%d ",0);
else printf("%d ",1);
}
}
【bzoj3567】江南乐的更多相关文章
- BZOJ-3576 江南乐 博弈+优化
fye测试原题,高一全跪,高二学长除了CA爷似乎都A辣(逃) 3576: [Hnoi2014]江南乐 Time Limit: 30 Sec Memory Limit: 512 MB Submit: 1 ...
- bzoj 3576[Hnoi2014]江南乐 sg函数+分块预处理
3576: [Hnoi2014]江南乐 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1929 Solved: 686[Submit][Status ...
- 【BZOJ3576】江南乐(博弈论)
[BZOJ3576]江南乐(博弈论) 题面 BZOJ 洛谷 题解 无论一堆石头怎么拆分,都并不能改变它是一个\(Multi-SG\)的事实. 既然每一组的\(F\)都是固定的,那么我们预处理所有的可能 ...
- 洛谷 P3235 [HNOI2014]江南乐 解题报告
P3235 [HNOI2014]江南乐 Description 两人进行 T 轮游戏,给定参数 F ,每轮给出 N 堆石子,先手和后手轮流选择石子数大于等于 F 的一堆,将其分成任意(大于1)堆,使得 ...
- 【LOJ】#2210. 「HNOI2014」江南乐
LOJ#2210. 「HNOI2014」江南乐 感觉是要推sg函数 发现\(\lfloor \frac{N}{i}\rfloor\)只有\(O(\sqrt{N})\)种取值 考虑把这些取值都拿出来,能 ...
- bzoj3576: [Hnoi2014]江南乐
Description 小A是一个名副其实的狂热的回合制游戏玩家.在获得了许多回合制游戏的世界级奖项之后,小A有一天突然想起了他小时候在江南玩过的一个回合制游戏. 游戏的规则是这样的,首先给定一 ...
- BZOJ 3576 江南乐
http://www.lydsy.com/JudgeOnline/problem.php?id=3576 思路:由于数字巨大,因此N^2异或做法是过不了的,我们考虑将n个石子分成i堆,那么会有n%i堆 ...
- [HNOI 2014]江南乐
Description 题库链接 给你指定一个数 \(f\) ,并给你 \(T\) 组游戏,每组有 \(n\) 堆石子, \(A,B\) 两人轮流对石子进行操作,每次你可以选择其中任意一堆数量不小于 ...
- [HNOI2014]江南乐
Description 小A是一个名副其实的狂热的回合制游戏玩家.在获得了许多回合制游戏的世界级奖项之后,小A有一天突然想起了他小时候在江南玩过的一个回合制游戏. 游戏的规则是这样的,首先给定一 ...
随机推荐
- Java EE JSP内置对象及表达式语言
一.JSP内置对象 JSP根据Servlet API规范提供了一些内置对象,开发者不用事先声明就可使用标准变量来访问这些对象. JSP提供了9种内置对象: (一).request 简述: JSP编程中 ...
- 8个数据清洗Python代码,复制可用,最长11行 | 资源
最近,大数据工程师Kin Lim Lee在Medium上发表了一篇文章,介绍了8个用于数据清洗的Python代码. 数据清洗,是进行数据分析和使用数据训练模型的必经之路,也是最耗费数据科学家/程序员精 ...
- Angular7运行机制--根据腾讯课堂米斯特吴 《Angular4从入门到实战》学习笔记分析完成
- linux常用的查看设备的命令
系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ...
- grunt requireJS 的基础配置
module.exports = function(grunt){ //grunt的配置我就不叨叨了 自己看官网就ok了 //我就介绍下grunt的依赖插件grunt-contrib-requirej ...
- html的背景样式图片
背景图片 如果背景图片小于当前的div的情况下 默认的是将平铺充满元素 background-image 设置背景图片. background-repeat 设置是否及如何重复背景图片. repeat ...
- 软银集团和共享办公空间公司WeWork在日本成立合资公司
[TechWeb报道]7月18日消息,据国外媒体报道,软银集团和共享办公空间公司WeWork联合宣布,在日本成立合资公司WeWork Japan. 该合资公司将在日本开设联合办公空间,于明年初在东京设 ...
- openresty 安装指南
对于一些常见的 Linux 发行版本,OpenResty 提供 官方预编译包.确保你首先用这种方式来安装. 如果您还没有下载 OpenResty 的源码包, 请到 Download 页下载. 首先,您 ...
- Divide by three, multiply by two(DFS+思维)
Polycarp likes to play with numbers. He takes some integer number x, writes it down on the board, an ...
- Scrum立会报告+燃尽图(十月三十日总第二十一次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2290 项目地址:https://git.coding.net/zhang ...